mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-30 01:52:51 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			39480 lines
		
	
	
		
			1.3 MiB
		
	
	
	
	
	
	
	
			
		
		
	
	
			39480 lines
		
	
	
		
			1.3 MiB
		
	
	
	
	
	
	
	
| From 369794a62050fadc47b617acb29e19d6f536fe3f Mon Sep 17 00:00:00 2001
 | |
| From: Felix Fietkau <nbd@nbd.name>
 | |
| Date: Sat, 24 Oct 2020 21:14:16 +0200
 | |
| Subject: [PATCH 03/27] kernel: add linux 5.10 support
 | |
| 
 | |
| Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| ---
 | |
|  include/image-commands.mk                     |    3 +-
 | |
|  package/base-files/files/lib/upgrade/nand.sh  |  102 +-
 | |
|  package/kernel/linux/modules/block.mk         |   16 +-
 | |
|  package/kernel/linux/modules/fs.mk            |    6 +-
 | |
|  package/kernel/linux/modules/netdevices.mk    |    2 +-
 | |
|  package/kernel/linux/modules/netfilter.mk     |    4 +-
 | |
|  package/kernel/linux/modules/usb.mk           |    2 +-
 | |
|  scripts/mkits.sh                              |   45 +-
 | |
|  ...dcode-path-to-awk-in-scripts-ld-vers.patch |   30 +
 | |
|  .../011-kbuild-export-SUBARCH.patch           |   21 +
 | |
|  ...a-neon-optimize-for-non-block-size-m.patch |  272 +
 | |
|  ...a-neon-add-missing-counter-increment.patch |   38 +
 | |
|  ...ut-frequently-used-members-above-cac.patch |   42 +
 | |
|  ...ow_offload-handle-netdevice-events-f.patch |  106 +
 | |
|  ...convert-fixed-partitions-to-the-json.patch |  324 +
 | |
|  ...move-partition-binding-to-its-own-fi.patch |  115 +
 | |
|  ...d-add-binding-for-BCM4908-partitions.patch |   92 +
 | |
|  ...art-support-BCM4908-fixed-partitions.patch |  654 ++
 | |
|  ...rt-limit-parsing-of-deprecated-DT-sy.patch |   69 +
 | |
|  ...rt-make-symbol-bcm4908_partitions_qu.patch |   34 +
 | |
|  ...em-cells-compatible-to-parse-mtd-as-.patch |   38 +
 | |
|  ...ings-nvmem-drop-nodename-restriction.patch |   25 +
 | |
|  ...Document-use-of-nvmem-cells-compatib.patch |  117 +
 | |
|  ...add-binding-for-Linksys-Northstar-pa.patch |   98 +
 | |
|  ...rt-support-Linksys-Northstar-partiti.patch |  156 +
 | |
|  ...pi-poll-functionality-to-__napi_poll.patch |   88 +
 | |
|  ...threaded-able-napi-poll-loop-support.patch |  261 +
 | |
|  ...tribute-to-control-napi-threaded-mod.patch |  177 +
 | |
|  ...ween-napi-kthread-mode-and-busy-poll.patch |   93 +
 | |
|  ...up-on-napi_disable-for-threaded-napi.patch |   53 +
 | |
|  ...y-switchdev-of-disappearance-of-old-.patch |  126 +
 | |
|  ...r-when-a-non-legacy-FDB-operation-fa.patch |   52 +
 | |
|  ...e-switchdev_notifier_fdb_info-in-dsa.patch |  226 +
 | |
|  ...tchdev-event-implementation-under-th.patch |   85 +
 | |
|  ...ly-in-dsa_slave_switchdev_event-if-w.patch |   42 +
 | |
|  ...or-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch |  264 +
 | |
|  ...setup-core-clock-even-in-TRGMII-mode.patch |   84 +
 | |
|  ..._nvram-rename-finding-function-and-i.patch |   80 +
 | |
|  ..._nvram-add-helper-checking-for-NVRAM.patch |   90 +
 | |
|  ...7xx_nvram-extract-code-copying-NVRAM.patch |   80 +
 | |
|  ..._nvram-look-for-NVRAM-with-for-inste.patch |   37 +
 | |
|  ..._nvram-inline-code-checking-NVRAM-si.patch |   70 +
 | |
|  ...rious-flag-to-disable-overcurrent-ch.patch |   88 +
 | |
|  ...-platform-add-spurious_oc-DT-support.patch |   31 +
 | |
|  target/linux/generic/config-5.10              | 7062 +++++++++++++++++
 | |
|  target/linux/generic/config-5.4               |    1 +
 | |
|  target/linux/generic/config-filter            |    6 +-
 | |
|  .../generic/files/block/partitions/fit.c      |  254 +
 | |
|  .../files/drivers/mtd/mtdsplit/Kconfig        |    5 +
 | |
|  .../files/drivers/mtd/mtdsplit/Makefile       |    1 +
 | |
|  .../drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c   |  186 +
 | |
|  .../files/drivers/mtd/mtdsplit/mtdsplit_fit.c |    6 +
 | |
|  .../generic/files/drivers/net/phy/ar8216.c    |   16 +
 | |
|  .../generic/hack-5.10/204-module_strip.patch  |  196 +
 | |
|  .../210-darwin_scripts_include.patch          | 3053 +++++++
 | |
|  .../211-darwin-uuid-typedef-clash.patch       |   22 +
 | |
|  .../hack-5.10/212-tools_portability.patch     |  110 +
 | |
|  .../hack-5.10/214-spidev_h_portability.patch  |   24 +
 | |
|  .../generic/hack-5.10/220-gc_sections.patch   |  120 +
 | |
|  .../hack-5.10/221-module_exports.patch        |  102 +
 | |
|  .../hack-5.10/230-openwrt_lzma_options.patch  |   34 +
 | |
|  .../hack-5.10/249-udp-tunnel-selection.patch  |   11 +
 | |
|  .../hack-5.10/250-netfilter_depends.patch     |   27 +
 | |
|  .../linux/generic/hack-5.10/251-kconfig.patch |  199 +
 | |
|  .../hack-5.10/259-regmap_dynamic.patch        |  135 +
 | |
|  .../260-crypto_test_dependencies.patch        |   52 +
 | |
|  .../hack-5.10/261-lib-arc4-unhide.patch       |   15 +
 | |
|  .../generic/hack-5.10/280-rfkill-stubs.patch  |   84 +
 | |
|  ...cache-use-more-efficient-cache-blast.patch |   64 +
 | |
|  .../301-mips_image_cmdline_hack.patch         |   38 +
 | |
|  .../321-powerpc_crtsavres_prereq.patch        |   38 +
 | |
|  .../400-block-fit-partition-parser.patch      |  177 +
 | |
|  .../generic/hack-5.10/531-debloat_lzma.patch  | 1040 +++
 | |
|  .../640-bridge-only-accept-EAP-locally.patch  |   82 +
 | |
|  ...lter-connmark-introduce-set-dscpmark.patch |  212 +
 | |
|  ...-netfilter-add-xt_FLOWOFFLOAD-target.patch |  820 ++
 | |
|  .../hack-5.10/651-wireless_mesh_header.patch  |   24 +
 | |
|  .../hack-5.10/660-fq_codel_defaults.patch     |   27 +
 | |
|  .../661-use_fq_codel_by_default.patch         |  100 +
 | |
|  .../700-swconfig_switch_drivers.patch         |  129 +
 | |
|  .../710-net-dsa-mv88e6xxx-default-VID-1.patch |   18 +
 | |
|  ...-dsa-mv88e6xxx-disable-ATU-violation.patch |   12 +
 | |
|  .../hack-5.10/773-bgmac-add-srab-switch.patch |   98 +
 | |
|  .../hack-5.10/901-debloat_sock_diag.patch     |  162 +
 | |
|  .../generic/hack-5.10/902-debloat_proc.patch  |  408 +
 | |
|  .../hack-5.10/904-debloat_dma_buf.patch       |   82 +
 | |
|  .../hack-5.10/910-kobject_uevent.patch        |   32 +
 | |
|  .../911-kobject_add_broadcast_uevent.patch    |   76 +
 | |
|  ...include-asm-rwonce.h-for-kernel-code.patch |   29 +
 | |
|  ...s-negative-stack-offsets-on-stack-tr.patch |   57 +
 | |
|  ...CPU_MIPS64-for-remaining-MIPS64-CPUs.patch |   36 +
 | |
|  ...e_mem_map-with-ARCH_PFN_OFFSET-calcu.patch |   82 +
 | |
|  ...0-add-linux-spidev-compatible-si3210.patch |   18 +
 | |
|  ...ame2-and-add-RENAME_WHITEOUT-support.patch |   78 +
 | |
|  ...41-jffs2-add-RENAME_EXCHANGE-support.patch |   73 +
 | |
|  .../142-jffs2-add-splice-ops.patch            |   20 +
 | |
|  ...ge_allow_receiption_on_disabled_port.patch |   45 +
 | |
|  ...-rs5c372-support_alarms_up_to_1_week.patch |   94 +
 | |
|  ...he_alarm_to_be_used_as_wakeup_source.patch |   70 +
 | |
|  .../pending-5.10/201-extra_optimization.patch |   31 +
 | |
|  .../203-kallsyms_uncompressed.patch           |  119 +
 | |
|  .../205-backtrace_module_info.patch           |   41 +
 | |
|  ...e-filenames-from-deps_initramfs-list.patch |   30 +
 | |
|  ...able_wilink_platform_without_drivers.patch |   20 +
 | |
|  .../270-platform-mikrotik-build-bits.patch    |   31 +
 | |
|  .../300-mips_expose_boot_raw.patch            |   40 +
 | |
|  .../302-mips_no_branch_likely.patch           |   22 +
 | |
|  .../pending-5.10/305-mips_module_reloc.patch  |  371 +
 | |
|  .../307-mips_highmem_offset.patch             |   19 +
 | |
|  .../pending-5.10/308-mips32r2_tune.patch      |   22 +
 | |
|  ...CPU-option-reporting-to-proc-cpuinfo.patch |  140 +
 | |
|  .../310-arm_module_unresolved_weak_sym.patch  |   22 +
 | |
|  ...boot-put-appended-dtb-into-a-section.patch |   36 +
 | |
|  ...t-command-line-parameters-from-users.patch |  281 +
 | |
|  .../332-arc-add-OWRTDTB-section.patch         |   84 +
 | |
|  ...able-unaligned-access-in-kernel-mode.patch |   24 +
 | |
|  ...ernel-XZ-compression-option-on-PPC_8.patch |   25 +
 | |
|  .../400-mtd-mtdsplit-support.patch            |  313 +
 | |
|  ...t-add-of_match_table-with-DT-binding.patch |   22 +
 | |
|  .../pending-5.10/420-mtd-redboot_space.patch  |   41 +
 | |
|  ...30-mtd-add-myloader-partition-parser.patch |  229 +
 | |
|  ...check-for-bad-blocks-when-calculatin.patch |   68 +
 | |
|  ...bcm47xxpart-detect-T_Meter-partition.patch |   37 +
 | |
|  ...mtd-add-routerbootpart-parser-config.patch |   38 +
 | |
|  ...mtd-cfi_cmdset_0002-no-erase_suspend.patch |   25 +
 | |
|  ...et_0002-add-buffer-write-cmd-timeout.patch |   17 +
 | |
|  ...25p80-mx-disable-software-protection.patch |   18 +
 | |
|  ...ort-limiting-4K-sectors-support-base.patch |   71 +
 | |
|  .../476-mtd-spi-nor-add-eon-en25q128.patch    |   18 +
 | |
|  .../479-mtd-spi-nor-add-xtx-xt25f128b.patch   |   79 +
 | |
|  .../480-mtd-set-rootfs-to-be-root-dev.patch   |   38 +
 | |
|  ...or-rework-broken-flash-reset-support.patch |  180 +
 | |
|  ...r-add-support-for-Gigadevice-GD25D05.patch |   22 +
 | |
|  .../483-mtd-spi-nor-add-gd25q512.patch        |   12 +
 | |
|  ...mtd-device-named-ubi-or-data-on-boot.patch |   97 +
 | |
|  ...to-create-ubiblock-device-for-rootfs.patch |   69 +
 | |
|  ...ting-ubi0-rootfs-in-init-do_mounts.c.patch |   51 +
 | |
|  ...ROOT_DEV-to-ubiblock-rootfs-if-unset.patch |   34 +
 | |
|  .../494-mtd-ubi-add-EOF-marker-support.patch  |   60 +
 | |
|  ...-mtd-core-add-get_mtd_device_by_node.patch |   75 +
 | |
|  ...-add-bindings-for-mtd-concat-devices.patch |   52 +
 | |
|  ...cat-add-dt-driver-for-concat-devices.patch |  216 +
 | |
|  ...-mtdconcat-select-readwrite-function.patch |   24 +
 | |
|  ...when-recursively-deleting-partitions.patch |   24 +
 | |
|  .../500-fs_cdrom_dependencies.patch           |   40 +
 | |
|  .../530-jffs2_make_lzma_available.patch       | 5180 ++++++++++++
 | |
|  .../pending-5.10/532-jffs2_eofdetect.patch    |   65 +
 | |
|  .../600-netfilter_conntrack_flush.patch       |   88 +
 | |
|  ...etfilter_match_bypass_default_checks.patch |  110 +
 | |
|  ...netfilter_match_bypass_default_table.patch |  106 +
 | |
|  ...netfilter_match_reduce_memory_access.patch |   22 +
 | |
|  ...-netfilter_optional_tcp_window_check.patch |   73 +
 | |
|  ...del-do-not-defer-queue-length-update.patch |   86 +
 | |
|  .../pending-5.10/630-packet_socket_type.patch |  138 +
 | |
|  ...table-add-hash-offset-field-to-tuple.patch |   52 +
 | |
|  ...filter-flowtable-add-xmit-path-types.patch |  188 +
 | |
|  ...arding-path-from-virtual-netdevice-a.patch |  170 +
 | |
|  ...lve-forwarding-path-for-vlan-devices.patch |   80 +
 | |
|  ...e-forwarding-path-for-bridge-devices.patch |   62 +
 | |
|  ...ble-use-dev_fill_forward_path-to-obt.patch |  191 +
 | |
|  ...ble-use-dev_fill_forward_path-to-obt.patch |  344 +
 | |
|  ...netfilter-flowtable-add-vlan-support.patch |  391 +
 | |
|  ...ter-flowtable-bridge-and-VLAN-suppor.patch |  107 +
 | |
|  ...ve-VLAN-tag-actions-in-forwarding-pa.patch |  207 +
 | |
|  ...ow_offload-add-bridge-vlan-filtering.patch |   31 +
 | |
|  ...forwarding-path-for-bridge-pppoe-dev.patch |  100 +
 | |
|  ...-forwarding-path-for-dsa-slave-ports.patch |   60 +
 | |
|  ...etfilter-flowtable-add-pppoe-support.patch |  263 +
 | |
|  ...ter-nft_flow_offload-add-dsa-support.patch |   30 +
 | |
|  ...ble-add-offload-support-for-xmit-pat.patch |  308 +
 | |
|  ...sa-slave-add-support-for-TC_SETUP_FT.patch |   53 +
 | |
|  ...ow_offload-use-direct-xmit-if-hardwa.patch |  108 +
 | |
|  ...w_table-fix-untagging-with-hardware-.patch |  122 +
 | |
|  ...w_offload-add-FLOW_ACTION_PPPOE_PUSH.patch |   26 +
 | |
|  ...ble-support-for-FLOW_ACTION_PPPOE_PU.patch |   31 +
 | |
|  .../pending-5.10/655-increase_skb_pad.patch   |   20 +
 | |
|  ...Add-support-for-MAP-E-FMRs-mesh-mode.patch |  511 ++
 | |
|  ...ng-with-source-address-failed-policy.patch |  263 +
 | |
|  ...nes-for-_POLICY_FAILED-until-all-cod.patch |   50 +
 | |
|  ...T-skip-GRO-for-foreign-MAC-addresses.patch |  149 +
 | |
|  .../681-NET-add-of_get_mac_address_mtd.patch  |  135 +
 | |
|  ...detach-callback-to-struct-phy_driver.patch |   38 +
 | |
|  ...net-phy-at803x-fix-at8033-sgmii-mode.patch |   51 +
 | |
|  ...760-net-dsa-mv88e6xxx-fix-vlan-setup.patch |   27 +
 | |
|  ...-net-dsa-mt7530-Support-EEE-features.patch |  121 +
 | |
|  ...hdev-Refactor-br_switchdev_fdb_notif.patch |   77 +
 | |
|  ...hdev-Include-local-flag-in-FDB-notif.patch |   42 +
 | |
|  ...hdev-Send-FDB-notifications-for-host.patch |   96 +
 | |
|  ...local-addresses-in-assisted-CPU-port.patch |   36 +
 | |
|  ...bridge-addresses-in-assisted-CPU-por.patch |   30 +
 | |
|  ...tic-FDB-entries-on-foreign-interface.patch |   56 +
 | |
|  ...equest-assisted-learning-on-CPU-port.patch |   27 +
 | |
|  ...net-mtk_eth_soc-use-napi_consume_skb.patch |   72 +
 | |
|  ..._eth_soc-significantly-reduce-mdio-b.patch |   26 +
 | |
|  ...rnet-mtk_eth_soc-fix-rx-vlan-offload.patch |   31 +
 | |
|  ..._eth_soc-fix-unnecessary-tx-queue-st.patch |   50 +
 | |
|  ..._eth_soc-use-larger-burst-size-for-q.patch |   32 +
 | |
|  ...-mtk_eth_soc-increase-DMA-ring-sizes.patch |   21 +
 | |
|  ..._eth_soc-implement-dynamic-interrupt.patch |  281 +
 | |
|  ..._eth_soc-cache-hardware-pointer-of-l.patch |   67 +
 | |
|  ..._eth_soc-only-read-the-full-rx-descr.patch |   44 +
 | |
|  ..._eth_soc-unmap-rx-data-before-callin.patch |   44 +
 | |
|  ..._eth_soc-avoid-rearming-interrupt-if.patch |   35 +
 | |
|  ...k_eth_soc-fix-parsing-packets-in-GDM.patch |   67 +
 | |
|  ..._eth_soc-set-PPE-flow-hash-as-skb-ha.patch |   41 +
 | |
|  ..._eth_soc-add-support-for-initializin.patch | 1307 +++
 | |
|  ..._eth_soc-add-flow-offloading-support.patch |  574 ++
 | |
|  ...ice-struct-copy-its-DMA-params-to-th.patch |   70 +
 | |
|  .../810-pci_disable_common_quirks.patch       |   62 +
 | |
|  .../811-pci_disable_usb_common_quirks.patch   |  115 +
 | |
|  ...problem-with-platfom-data-in-w1-gpio.patch |   26 +
 | |
|  .../pending-5.10/834-ledtrig-libata.patch     |  149 +
 | |
|  ...40-hwrng-bcm2835-set-quality-to-1000.patch |   26 +
 | |
|  .../pending-5.10/920-mangle_bootargs.patch    |   71 +
 | |
|  214 files changed, 37406 insertions(+), 54 deletions(-)
 | |
|  create mode 100644 target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/071-crypto-arm-chacha-neon-optimize-for-non-block-size-m.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/072-crypto-arm-chacha-neon-add-missing-counter-increment.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/080-wireguard-peer-put-frequently-used-members-above-cac.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/402-v5.12-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/402-v5.12-0002-dt-bindings-mtd-add-binding-for-BCM4908-partitions.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/403-v5.13-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/404-v5.13-mtd-parsers-ofpart-limit-parsing-of-deprecated-DT-sy.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/405-v5.13-mtd-parsers-ofpart-make-symbol-bcm4908_partitions_qu.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/406-v5.13-0001-mtd-core-add-nvmem-cells-compatible-to-parse-mtd-as-.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/406-v5.13-0002-dt-bindings-nvmem-drop-nodename-restriction.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/406-v5.13-0003-dt-bindings-mtd-Document-use-of-nvmem-cells-compatib.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/407-v5.13-0001-dt-bindings-mtd-add-binding-for-Linksys-Northstar-pa.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/407-v5.13-0002-mtd-parsers-ofpart-support-Linksys-Northstar-partiti.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/600-v5.12-net-extract-napi-poll-functionality-to-__napi_poll.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/601-v5.12-net-implement-threaded-able-napi-poll-loop-support.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/602-v5.12-net-add-sysfs-attribute-to-control-napi-threaded-mod.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/603-v5.12-net-fix-race-between-napi-kthread-mode-and-busy-poll.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/770-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/800-v5.13-0001-firmware-bcm47xx_nvram-rename-finding-function-and-i.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/800-v5.13-0002-firmware-bcm47xx_nvram-add-helper-checking-for-NVRAM.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/800-v5.13-0003-firmware-bcm47xx_nvram-extract-code-copying-NVRAM.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/800-v5.13-0004-firmware-bcm47xx_nvram-look-for-NVRAM-with-for-inste.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/800-v5.13-0005-firmware-bcm47xx_nvram-inline-code-checking-NVRAM-si.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/810-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch
 | |
|  create mode 100644 target/linux/generic/backport-5.10/811-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch
 | |
|  create mode 100644 target/linux/generic/config-5.10
 | |
|  create mode 100644 target/linux/generic/files/block/partitions/fit.c
 | |
|  create mode 100644 target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c
 | |
|  create mode 100644 target/linux/generic/hack-5.10/204-module_strip.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/210-darwin_scripts_include.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/212-tools_portability.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/214-spidev_h_portability.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/220-gc_sections.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/221-module_exports.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/250-netfilter_depends.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/251-kconfig.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/259-regmap_dynamic.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/280-rfkill-stubs.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/531-debloat_lzma.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/651-wireless_mesh_header.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/660-fq_codel_defaults.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/902-debloat_proc.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/904-debloat_dma_buf.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/910-kobject_uevent.patch
 | |
|  create mode 100644 target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/103-MIPS-select-CPU_MIPS64-for-remaining-MIPS64-CPUs.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/201-extra_optimization.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/205-backtrace_module_info.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/305-mips_module_reloc.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/307-mips_highmem_offset.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/308-mips32r2_tune.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/420-mtd-redboot_space.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/483-mtd-spi-nor-add-gd25q512.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/499-mtd-don-t-lock-when-recursively-deleting-partitions.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/630-packet_socket_type.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-10-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-11-net-ppp-resolve-forwarding-path-for-bridge-pppoe-dev.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-13-netfilter-flowtable-add-pppoe-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-dsa-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-15-netfilter-flowtable-add-offload-support-for-xmit-pat.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-17-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-18-netfilter-nf_flow_table-fix-untagging-with-hardware-.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-19-net-flow_offload-add-FLOW_ACTION_PPPOE_PUSH.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/640-20-netfilter-flowtable-support-for-FLOW_ACTION_PPPOE_PU.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/655-increase_skb_pad.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/762-net-bridge-switchdev-Refactor-br_switchdev_fdb_notif.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/763-net-bridge-switchdev-Include-local-flag-in-FDB-notif.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/764-net-bridge-switchdev-Send-FDB-notifications-for-host.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/834-ledtrig-libata.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/840-hwrng-bcm2835-set-quality-to-1000.patch
 | |
|  create mode 100644 target/linux/generic/pending-5.10/920-mangle_bootargs.patch
 | |
| 
 | |
| diff --git a/include/image-commands.mk b/include/image-commands.mk
 | |
| index 4d54a14ba4..2c917d613e 100644
 | |
| --- a/include/image-commands.mk
 | |
| +++ b/include/image-commands.mk
 | |
| @@ -200,11 +200,12 @@ define Build/fit
 | |
|  	$(TOPDIR)/scripts/mkits.sh \
 | |
|  		-D $(DEVICE_NAME) -o $@.its -k $@ \
 | |
|  		$(if $(word 2,$(1)),-d $(word 2,$(1))) -C $(word 1,$(1)) \
 | |
| +		$(if $(word 3,$(1)),-r $(IMAGE_ROOTFS) -f $(subst _,$(comma),$(DEVICE_NAME))) \
 | |
|  		-a $(KERNEL_LOADADDR) -e $(if $(KERNEL_ENTRY),$(KERNEL_ENTRY),$(KERNEL_LOADADDR)) \
 | |
|  		$(if $(DEVICE_FDT_NUM),-n $(DEVICE_FDT_NUM)) \
 | |
|  		-c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config@1") \
 | |
|  		-A $(LINUX_KARCH) -v $(LINUX_VERSION)
 | |
| -	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage -f $@.its $@.new
 | |
| +	PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(word 3,$(1)),-E -B 0x1000 -p 0x1000) -f $@.its $@.new
 | |
|  	@mv $@.new $@
 | |
|  endef
 | |
|  
 | |
| diff --git a/package/base-files/files/lib/upgrade/nand.sh b/package/base-files/files/lib/upgrade/nand.sh
 | |
| index e6f58df4f5..5bc9ff83f9 100644
 | |
| --- a/package/base-files/files/lib/upgrade/nand.sh
 | |
| +++ b/package/base-files/files/lib/upgrade/nand.sh
 | |
| @@ -3,13 +3,13 @@
 | |
|  
 | |
|  . /lib/functions.sh
 | |
|  
 | |
| -# 'kernel' partition on NAND contains the kernel
 | |
| +# 'kernel' partition or UBI volume on NAND contains the kernel
 | |
|  CI_KERNPART="${CI_KERNPART:-kernel}"
 | |
|  
 | |
|  # 'ubi' partition on NAND contains UBI
 | |
|  CI_UBIPART="${CI_UBIPART:-ubi}"
 | |
|  
 | |
| -# 'rootfs' partition on NAND contains the rootfs
 | |
| +# 'rootfs' UBI volume on NAND contains the rootfs
 | |
|  CI_ROOTPART="${CI_ROOTPART:-rootfs}"
 | |
|  
 | |
|  ubi_mknod() {
 | |
| @@ -117,9 +117,11 @@ nand_restore_config() {
 | |
|  nand_upgrade_prepare_ubi() {
 | |
|  	local rootfs_length="$1"
 | |
|  	local rootfs_type="$2"
 | |
| -	local has_kernel="${3:-0}"
 | |
| +	local kernel_length="$3"
 | |
|  	local has_env="${4:-0}"
 | |
|  
 | |
| +	[ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1
 | |
| +
 | |
|  	local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
 | |
|  	if [ ! "$mtdnum" ]; then
 | |
|  		echo "cannot find ubi mtd partition $CI_UBIPART"
 | |
| @@ -148,23 +150,24 @@ nand_upgrade_prepare_ubi() {
 | |
|  	local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
 | |
|  	local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
 | |
|  
 | |
| -	# remove ubiblock device of rootfs
 | |
| -	local root_ubiblk="ubiblock${root_ubivol:3}"
 | |
| -	if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then
 | |
| -		echo "removing $root_ubiblk"
 | |
| -		if ! ubiblock -r /dev/$root_ubivol; then
 | |
| -			echo "cannot remove $root_ubiblk"
 | |
| -			return 1;
 | |
| +	local ubiblk ubiblkvol
 | |
| +	for ubiblk in /dev/ubiblock*_? ; do
 | |
| +		[ -e "$ubiblk" ] || continue
 | |
| +		echo "removing ubiblock${ubiblk:13}"
 | |
| +		ubiblkvol=ubi${ubiblk:13}
 | |
| +		if ! ubiblock -r /dev/$ubiblkvol; then
 | |
| +			echo "cannot remove $ubiblk"
 | |
| +			return 1
 | |
|  		fi
 | |
| -	fi
 | |
| +	done
 | |
|  
 | |
|  	# kill volumes
 | |
|  	[ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
 | |
| -	[ "$root_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
 | |
| +	[ "$root_ubivol" -a "$root_ubivol" != "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
 | |
|  	[ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
 | |
|  
 | |
|  	# update kernel
 | |
| -	if [ "$has_kernel" = "1" ]; then
 | |
| +	if [ -n "$kernel_length" ]; then
 | |
|  		if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
 | |
|  			echo "cannot create kernel volume"
 | |
|  			return 1;
 | |
| @@ -172,15 +175,17 @@ nand_upgrade_prepare_ubi() {
 | |
|  	fi
 | |
|  
 | |
|  	# update rootfs
 | |
| -	local root_size_param
 | |
| -	if [ "$rootfs_type" = "ubifs" ]; then
 | |
| -		root_size_param="-m"
 | |
| -	else
 | |
| -		root_size_param="-s $rootfs_length"
 | |
| -	fi
 | |
| -	if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $root_size_param; then
 | |
| -		echo "cannot create rootfs volume"
 | |
| -		return 1;
 | |
| +	if [ -n "$rootfs_length" ]; then
 | |
| +		local root_size_param
 | |
| +		if [ "$rootfs_type" = "ubifs" ]; then
 | |
| +			root_size_param="-m"
 | |
| +		else
 | |
| +			root_size_param="-s $rootfs_length"
 | |
| +		fi
 | |
| +		if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then
 | |
| +			echo "cannot create rootfs volume"
 | |
| +			return 1;
 | |
| +		fi
 | |
|  	fi
 | |
|  
 | |
|  	# create rootfs_data for non-ubifs rootfs
 | |
| @@ -232,7 +237,7 @@ nand_upgrade_ubinized() {
 | |
|  nand_upgrade_ubifs() {
 | |
|  	local rootfs_length=$( (cat $1 | wc -c) 2> /dev/null)
 | |
|  
 | |
| -	nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "0" "0"
 | |
| +	nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "" ""
 | |
|  
 | |
|  	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
 | |
|  	local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
 | |
| @@ -241,39 +246,59 @@ nand_upgrade_ubifs() {
 | |
|  	nand_do_upgrade_success
 | |
|  }
 | |
|  
 | |
| +nand_upgrade_fit() {
 | |
| +	local fit_file="$1"
 | |
| +	local fit_length="$(wc -c < "$fit_file")"
 | |
| +
 | |
| +	nand_upgrade_prepare_ubi "" "" "$fit_length" "1"
 | |
| +
 | |
| +	local fit_ubidev="$(nand_find_ubi "$CI_UBIPART")"
 | |
| +	local fit_ubivol="$(nand_find_volume $fit_ubidev "$CI_KERNPART")"
 | |
| +	ubiupdatevol /dev/$fit_ubivol -s $fit_length $fit_file
 | |
| +
 | |
| +	nand_do_upgrade_success
 | |
| +}
 | |
| +
 | |
|  nand_upgrade_tar() {
 | |
|  	local tar_file="$1"
 | |
|  	local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
 | |
|  
 | |
| -	local board_dir=$(tar tf $tar_file | grep -m 1 '^sysupgrade-.*/$')
 | |
| +	local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$')
 | |
|  	board_dir=${board_dir%/}
 | |
|  
 | |
| -	local kernel_length=$( (tar xf $tar_file ${board_dir}/kernel -O | wc -c) 2> /dev/null)
 | |
| -	local rootfs_length=$( (tar xf $tar_file ${board_dir}/root -O | wc -c) 2> /dev/null)
 | |
| +	kernel_length=$( (tar xf "$tar_file" ${board_dir}/kernel -O | wc -c) 2> /dev/null)
 | |
| +	local has_rootfs=0
 | |
| +	local rootfs_length
 | |
| +	local rootfs_type
 | |
|  
 | |
| -	local rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
 | |
| +	tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1
 | |
| +	[ "$has_rootfs" = "1" ] && {
 | |
| +		rootfs_length=$( (tar xf "$tar_file" ${board_dir}/root -O | wc -c) 2> /dev/null)
 | |
| +		rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
 | |
| +	}
 | |
|  
 | |
|  	local has_kernel=1
 | |
|  	local has_env=0
 | |
|  
 | |
|  	[ "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
 | |
| -		tar xf $tar_file ${board_dir}/kernel -O | mtd write - $CI_KERNPART
 | |
| +		tar xf "$tar_file" ${board_dir}/kernel -O | mtd write - $CI_KERNPART
 | |
|  	}
 | |
| -	[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=0
 | |
| +	[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=
 | |
|  
 | |
| -	nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "$has_kernel" "$has_env"
 | |
| +	nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "${has_kernel:+$kernel_length}" "$has_env"
 | |
|  
 | |
|  	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
 | |
|  	[ "$has_kernel" = "1" ] && {
 | |
| -		local kern_ubivol="$(nand_find_volume $ubidev $CI_KERNPART)"
 | |
| -		tar xf $tar_file ${board_dir}/kernel -O | \
 | |
| +		local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
 | |
| +		tar xf "$tar_file" ${board_dir}/kernel -O | \
 | |
|  			ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
 | |
|  	}
 | |
|  
 | |
| -	local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
 | |
| -	tar xf $tar_file ${board_dir}/root -O | \
 | |
| -		ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
 | |
| -
 | |
| +	[ "$has_rootfs" = "1" ] && {
 | |
| +		local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
 | |
| +		tar xf "$tar_file" ${board_dir}/root -O | \
 | |
| +			ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
 | |
| +	}
 | |
|  	nand_do_upgrade_success
 | |
|  }
 | |
|  
 | |
| @@ -281,9 +306,10 @@ nand_upgrade_tar() {
 | |
|  nand_do_upgrade() {
 | |
|  	local file_type=$(identify $1)
 | |
|  
 | |
| -	[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
 | |
| +	[ ! "$( find_mtd_index "$CI_UBIPART" )" ] && CI_UBIPART="rootfs"
 | |
|  
 | |
|  	case "$file_type" in
 | |
| +		"fit")		nand_upgrade_fit $1;;
 | |
|  		"ubi")		nand_upgrade_ubinized $1;;
 | |
|  		"ubifs")	nand_upgrade_ubifs $1;;
 | |
|  		*)		nand_upgrade_tar $1;;
 | |
| @@ -309,7 +335,7 @@ nand_do_platform_check() {
 | |
|  	local control_length=$( (tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null)
 | |
|  	local file_type="$(identify $2)"
 | |
|  
 | |
| -	[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" ] && {
 | |
| +	[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" -a "$file_type" != "fit" ] && {
 | |
|  		echo "Invalid sysupgrade file."
 | |
|  		return 1
 | |
|  	}
 | |
| diff --git a/package/kernel/linux/modules/block.mk b/package/kernel/linux/modules/block.mk
 | |
| index 373c9fbaab..b7767b3d16 100644
 | |
| --- a/package/kernel/linux/modules/block.mk
 | |
| +++ b/package/kernel/linux/modules/block.mk
 | |
| @@ -537,16 +537,24 @@ endef
 | |
|  $(eval $(call KernelPackage,scsi-generic))
 | |
|  
 | |
|  
 | |
| +define KernelPackage/cdrom
 | |
| +  TITLE:=Kernel library module for CD / DVD drives
 | |
| +  KCONFIG:=CONFIG_CDROM
 | |
| +  HIDDEN:=1
 | |
| +  FILES:=$(LINUX_DIR)/drivers/cdrom/cdrom.ko
 | |
| +endef
 | |
| +
 | |
| +$(eval $(call KernelPackage,cdrom))
 | |
| +
 | |
| +
 | |
|  define KernelPackage/scsi-cdrom
 | |
|    SUBMENU:=$(BLOCK_MENU)
 | |
|    TITLE:=Kernel support for CD / DVD drives
 | |
| -  DEPENDS:=+kmod-scsi-core
 | |
| +  DEPENDS:=+kmod-scsi-core +kmod-cdrom
 | |
|    KCONFIG:= \
 | |
|      CONFIG_BLK_DEV_SR \
 | |
|      CONFIG_BLK_DEV_SR_VENDOR=n
 | |
| -  FILES:= \
 | |
| -    $(LINUX_DIR)/drivers/cdrom/cdrom.ko \
 | |
| -    $(LINUX_DIR)/drivers/scsi/sr_mod.ko
 | |
| +  FILES:=$(LINUX_DIR)/drivers/scsi/sr_mod.ko
 | |
|    AUTOLOAD:=$(call AutoLoad,45,sr_mod)
 | |
|  endef
 | |
|  
 | |
| diff --git a/package/kernel/linux/modules/fs.mk b/package/kernel/linux/modules/fs.mk
 | |
| index d43542b17e..a0db14ecfe 100644
 | |
| --- a/package/kernel/linux/modules/fs.mk
 | |
| +++ b/package/kernel/linux/modules/fs.mk
 | |
| @@ -243,6 +243,7 @@ $(eval $(call KernelPackage,fs-fscache))
 | |
|  define KernelPackage/fs-hfs
 | |
|    SUBMENU:=$(FS_MENU)
 | |
|    TITLE:=HFS filesystem support
 | |
| +  DEPENDS:=+kmod-cdrom
 | |
|    KCONFIG:=CONFIG_HFS_FS
 | |
|    FILES:=$(LINUX_DIR)/fs/hfs/hfs.ko
 | |
|    AUTOLOAD:=$(call AutoLoad,30,hfs)
 | |
| @@ -259,6 +260,7 @@ $(eval $(call KernelPackage,fs-hfs))
 | |
|  define KernelPackage/fs-hfsplus
 | |
|    SUBMENU:=$(FS_MENU)
 | |
|    TITLE:=HFS+ filesystem support
 | |
| +  DEPENDS:=+kmod-cdrom
 | |
|    KCONFIG:=CONFIG_HFSPLUS_FS
 | |
|    FILES:=$(LINUX_DIR)/fs/hfsplus/hfsplus.ko
 | |
|    AUTOLOAD:=$(call AutoLoad,30,hfsplus)
 | |
| @@ -275,7 +277,7 @@ $(eval $(call KernelPackage,fs-hfsplus))
 | |
|  define KernelPackage/fs-isofs
 | |
|    SUBMENU:=$(FS_MENU)
 | |
|    TITLE:=ISO9660 filesystem support
 | |
| -  DEPENDS:=+kmod-lib-zlib-inflate
 | |
| +  DEPENDS:=+kmod-lib-zlib-inflate +kmod-cdrom
 | |
|    KCONFIG:=CONFIG_ISO9660_FS CONFIG_JOLIET=y CONFIG_ZISOFS=n
 | |
|    FILES:=$(LINUX_DIR)/fs/isofs/isofs.ko
 | |
|    AUTOLOAD:=$(call AutoLoad,30,isofs)
 | |
| @@ -513,7 +515,7 @@ define KernelPackage/fs-udf
 | |
|    KCONFIG:=CONFIG_UDF_FS
 | |
|    FILES:=$(LINUX_DIR)/fs/udf/udf.ko
 | |
|    AUTOLOAD:=$(call AutoLoad,30,udf)
 | |
| -  DEPENDS:=+kmod-lib-crc-itu-t
 | |
| +  DEPENDS:=+kmod-lib-crc-itu-t +kmod-cdrom
 | |
|    $(call AddDepends/nls)
 | |
|  endef
 | |
|  
 | |
| diff --git a/package/kernel/linux/modules/netdevices.mk b/package/kernel/linux/modules/netdevices.mk
 | |
| index 901bddddea..5f7a80bf22 100644
 | |
| --- a/package/kernel/linux/modules/netdevices.mk
 | |
| +++ b/package/kernel/linux/modules/netdevices.mk
 | |
| @@ -1178,7 +1178,7 @@ $(eval $(call KernelPackage,sfp))
 | |
|  define KernelPackage/igc
 | |
|    SUBMENU:=$(NETWORK_DEVICES_MENU)
 | |
|    TITLE:=Intel(R) Ethernet Controller I225 Series support
 | |
| -  DEPENDS:=@PCI_SUPPORT
 | |
| +  DEPENDS:=@PCI_SUPPORT +kmod-ptp
 | |
|    KCONFIG:=CONFIG_IGC
 | |
|    FILES:=$(LINUX_DIR)/drivers/net/ethernet/intel/igc/igc.ko
 | |
|    AUTOLOAD:=$(call AutoProbe,igc)
 | |
| diff --git a/package/kernel/linux/modules/netfilter.mk b/package/kernel/linux/modules/netfilter.mk
 | |
| index b46fcebc08..e2bb1d0681 100644
 | |
| --- a/package/kernel/linux/modules/netfilter.mk
 | |
| +++ b/package/kernel/linux/modules/netfilter.mk
 | |
| @@ -155,7 +155,7 @@ define KernelPackage/nf-flow
 | |
|    DEPENDS:=+kmod-nf-conntrack
 | |
|    FILES:= \
 | |
|  	$(LINUX_DIR)/net/netfilter/nf_flow_table.ko \
 | |
| -	$(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko
 | |
| +	$(if $(CONFIG_LINUX_5_4),$(LINUX_DIR)/net/netfilter/nf_flow_table_hw.ko)
 | |
|    AUTOLOAD:=$(call AutoProbe,nf_flow_table nf_flow_table_hw)
 | |
|  endef
 | |
|  
 | |
| @@ -1052,7 +1052,7 @@ $(eval $(call KernelPackage,ipt-rpfilter))
 | |
|  define KernelPackage/nft-core
 | |
|    SUBMENU:=$(NF_MENU)
 | |
|    TITLE:=Netfilter nf_tables support
 | |
| -  DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +IPV6:kmod-nf-reject6 +IPV6:kmod-nf-conntrack6 +kmod-nf-nat
 | |
| +  DEPENDS:=+kmod-nfnetlink +kmod-nf-reject +IPV6:kmod-nf-reject6 +IPV6:kmod-nf-conntrack6 +kmod-nf-nat +kmod-lib-crc32c
 | |
|    FILES:=$(foreach mod,$(NFT_CORE-m),$(LINUX_DIR)/net/$(mod).ko)
 | |
|    AUTOLOAD:=$(call AutoProbe,$(notdir $(NFT_CORE-m)))
 | |
|    KCONFIG:= \
 | |
| diff --git a/package/kernel/linux/modules/usb.mk b/package/kernel/linux/modules/usb.mk
 | |
| index 93f99f7cbe..4191590ba7 100644
 | |
| --- a/package/kernel/linux/modules/usb.mk
 | |
| +++ b/package/kernel/linux/modules/usb.mk
 | |
| @@ -1387,7 +1387,7 @@ define KernelPackage/usb-net-cdc-ncm
 | |
|    KCONFIG:=CONFIG_USB_NET_CDC_NCM
 | |
|    FILES:= $(LINUX_DIR)/drivers/$(USBNET_DIR)/cdc_ncm.ko
 | |
|    AUTOLOAD:=$(call AutoProbe,cdc_ncm)
 | |
| -  $(call AddDepends/usb-net)
 | |
| +  $(call AddDepends/usb-net,+kmod-usb-net-cdc-ether)
 | |
|  endef
 | |
|  
 | |
|  define KernelPackage/usb-net-cdc-ncm/description
 | |
| diff --git a/scripts/mkits.sh b/scripts/mkits.sh
 | |
| index bb629d6fca..3d68fdacbc 100755
 | |
| --- a/scripts/mkits.sh
 | |
| +++ b/scripts/mkits.sh
 | |
| @@ -23,18 +23,23 @@ usage() {
 | |
|  	printf "\n\t-c ==> set config name 'config'"
 | |
|  	printf "\n\t-a ==> set load address to 'addr' (hex)"
 | |
|  	printf "\n\t-e ==> set entry point to 'entry' (hex)"
 | |
| +	printf "\n\t-f ==> set device tree compatible string"
 | |
|  	printf "\n\t-v ==> set kernel version to 'version'"
 | |
|  	printf "\n\t-k ==> include kernel image 'kernel'"
 | |
|  	printf "\n\t-D ==> human friendly Device Tree Blob 'name'"
 | |
|  	printf "\n\t-n ==> fdt unit-address 'address'"
 | |
|  	printf "\n\t-d ==> include Device Tree Blob 'dtb'"
 | |
| +	printf "\n\t-r ==> include RootFS blob"
 | |
| +	printf "\n\t-H ==> specify hash algo instead of SHA1"
 | |
|  	printf "\n\t-o ==> create output file 'its_file'\n"
 | |
|  	exit 1
 | |
|  }
 | |
|  
 | |
|  FDTNUM=1
 | |
| +ROOTFSNUM=1
 | |
| +HASH=sha1
 | |
|  
 | |
| -while getopts ":A:a:c:C:D:d:e:k:n:o:v:" OPTION
 | |
| +while getopts ":A:a:c:C:D:d:e:f:k:n:o:v:r:S" OPTION
 | |
|  do
 | |
|  	case $OPTION in
 | |
|  		A ) ARCH=$OPTARG;;
 | |
| @@ -44,9 +49,12 @@ do
 | |
|  		D ) DEVICE=$OPTARG;;
 | |
|  		d ) DTB=$OPTARG;;
 | |
|  		e ) ENTRY_ADDR=$OPTARG;;
 | |
| +		f ) COMPATIBLE=$OPTARG;;
 | |
|  		k ) KERNEL=$OPTARG;;
 | |
|  		n ) FDTNUM=$OPTARG;;
 | |
|  		o ) OUTPUT=$OPTARG;;
 | |
| +		r ) ROOTFS=$OPTARG;;
 | |
| +		S ) HASH=$OPTARG;;
 | |
|  		v ) VERSION=$OPTARG;;
 | |
|  		* ) echo "Invalid option passed to '$0' (options:$*)"
 | |
|  		usage;;
 | |
| @@ -62,11 +70,16 @@ fi
 | |
|  
 | |
|  ARCH_UPPER=$(echo "$ARCH" | tr '[:lower:]' '[:upper:]')
 | |
|  
 | |
| +if [ -n "${COMPATIBLE}" ]; then
 | |
| +	COMPATIBLE_PROP="compatible = \"${COMPATIBLE}\";"
 | |
| +fi
 | |
| +
 | |
|  # Conditionally create fdt information
 | |
|  if [ -n "${DTB}" ]; then
 | |
|  	FDT_NODE="
 | |
|  		fdt@$FDTNUM {
 | |
|  			description = \"${ARCH_UPPER} OpenWrt ${DEVICE} device tree blob\";
 | |
| +			${COMPATIBLE_PROP}
 | |
|  			data = /incbin/(\"${DTB}\");
 | |
|  			type = \"flat_dt\";
 | |
|  			arch = \"${ARCH}\";
 | |
| @@ -75,13 +88,34 @@ if [ -n "${DTB}" ]; then
 | |
|  				algo = \"crc32\";
 | |
|  			};
 | |
|  			hash@2 {
 | |
| -				algo = \"sha1\";
 | |
| +				algo = \"${HASH}\";
 | |
|  			};
 | |
|  		};
 | |
|  "
 | |
|  	FDT_PROP="fdt = \"fdt@$FDTNUM\";"
 | |
|  fi
 | |
|  
 | |
| +if [ -n "${ROOTFS}" ]; then
 | |
| +	dd if="${ROOTFS}" of="${ROOTFS}.pagesync" bs=4096 conv=sync
 | |
| +	ROOTFS_NODE="
 | |
| +		rootfs@$ROOTFSNUM {
 | |
| +			description = \"${ARCH_UPPER} OpenWrt ${DEVICE} rootfs\";
 | |
| +			${COMPATIBLE_PROP}
 | |
| +			data = /incbin/(\"${ROOTFS}.pagesync\");
 | |
| +			type = \"filesystem\";
 | |
| +			arch = \"${ARCH}\";
 | |
| +			compression = \"none\";
 | |
| +			hash@1 {
 | |
| +				algo = \"crc32\";
 | |
| +			};
 | |
| +			hash@2 {
 | |
| +				algo = \"${HASH}\";
 | |
| +			};
 | |
| +		};
 | |
| +"
 | |
| +	ROOTFS_PROP="loadables = \"rootfs@${ROOTFSNUM}\";"
 | |
| +fi
 | |
| +
 | |
|  # Create a default, fully populated DTS file
 | |
|  DATA="/dts-v1/;
 | |
|  
 | |
| @@ -103,18 +137,21 @@ DATA="/dts-v1/;
 | |
|  				algo = \"crc32\";
 | |
|  			};
 | |
|  			hash@2 {
 | |
| -				algo = \"sha1\";
 | |
| +				algo = \"$HASH\";
 | |
|  			};
 | |
|  		};
 | |
|  ${FDT_NODE}
 | |
| +${ROOTFS_NODE}
 | |
|  	};
 | |
|  
 | |
|  	configurations {
 | |
|  		default = \"${CONFIG}\";
 | |
|  		${CONFIG} {
 | |
| -			description = \"OpenWrt\";
 | |
| +			description = \"OpenWrt ${DEVICE}\";
 | |
|  			kernel = \"kernel@1\";
 | |
|  			${FDT_PROP}
 | |
| +			${ROOTFS_PROP}
 | |
| +			${COMPATIBLE_PROP}
 | |
|  		};
 | |
|  	};
 | |
|  };"
 | |
| diff --git a/target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch b/target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch
 | |
| new file mode 100644
 | |
| index 0000000000..7ac4f9d240
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/010-Kbuild-don-t-hardcode-path-to-awk-in-scripts-ld-vers.patch
 | |
| @@ -0,0 +1,30 @@
 | |
| +From 13b1ecc3401653a355798eb1dee10cc1608202f4 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Mon, 18 Jan 2016 12:27:49 +0100
 | |
| +Subject: [PATCH 33/34] Kbuild: don't hardcode path to awk in
 | |
| + scripts/ld-version.sh
 | |
| +
 | |
| +On some systems /usr/bin/awk does not exist, or is broken. Find it via
 | |
| +$PATH instead.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + scripts/ld-version.sh | 4 +++-
 | |
| + 1 file changed, 3 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/scripts/ld-version.sh
 | |
| ++++ b/scripts/ld-version.sh
 | |
| +@@ -1,6 +1,7 @@
 | |
| +-#!/usr/bin/awk -f
 | |
| ++#!/bin/sh
 | |
| + # SPDX-License-Identifier: GPL-2.0
 | |
| + # extract linker version number from stdin and turn into single number
 | |
| ++exec awk '
 | |
| + 	{
 | |
| + 	gsub(".*\\)", "");
 | |
| + 	gsub(".*version ", "");
 | |
| +@@ -9,3 +10,4 @@
 | |
| + 	print a[1]*100000000 + a[2]*1000000 + a[3]*10000;
 | |
| + 	exit
 | |
| + 	}
 | |
| ++'
 | |
| diff --git a/target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch b/target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch
 | |
| new file mode 100644
 | |
| index 0000000000..bb99e4ddbf
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/011-kbuild-export-SUBARCH.patch
 | |
| @@ -0,0 +1,21 @@
 | |
| +From 173019b66dcc9d68ad9333aa744dad1e369b5aa8 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sun, 9 Jul 2017 00:26:53 +0200
 | |
| +Subject: [PATCH 34/34] kernel: add compile fix for linux 4.9 on x86
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + Makefile | 4 ++--
 | |
| + 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| +
 | |
| +--- a/Makefile
 | |
| ++++ b/Makefile
 | |
| +@@ -507,7 +507,7 @@ KBUILD_LDFLAGS_MODULE :=
 | |
| + KBUILD_LDFLAGS :=
 | |
| + CLANG_FLAGS :=
 | |
| + 
 | |
| +-export ARCH SRCARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC
 | |
| ++export ARCH SRCARCH SUBARCH CONFIG_SHELL BASH HOSTCC KBUILD_HOSTCFLAGS CROSS_COMPILE LD CC
 | |
| + export CPP AR NM STRIP OBJCOPY OBJDUMP READELF PAHOLE RESOLVE_BTFIDS LEX YACC AWK INSTALLKERNEL
 | |
| + export PERL PYTHON PYTHON3 CHECK CHECKFLAGS MAKE UTS_MACHINE HOSTCXX
 | |
| + export KGZIP KBZIP2 KLZOP LZMA LZ4 XZ ZSTD
 | |
| diff --git a/target/linux/generic/backport-5.10/071-crypto-arm-chacha-neon-optimize-for-non-block-size-m.patch b/target/linux/generic/backport-5.10/071-crypto-arm-chacha-neon-optimize-for-non-block-size-m.patch
 | |
| new file mode 100644
 | |
| index 0000000000..b1f46e9af8
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/071-crypto-arm-chacha-neon-optimize-for-non-block-size-m.patch
 | |
| @@ -0,0 +1,272 @@
 | |
| +From 03662fcd41f4b764857f17b95f9a2a63c24bddd4 Mon Sep 17 00:00:00 2001
 | |
| +From: Ard Biesheuvel <ardb@kernel.org>
 | |
| +Date: Tue, 3 Nov 2020 17:28:09 +0100
 | |
| +Subject: [PATCH 1/2] crypto: arm/chacha-neon - optimize for non-block size
 | |
| + multiples
 | |
| +
 | |
| +commit 86cd97ec4b943af35562a74688bc4e909b32c3d1 upstream.
 | |
| +
 | |
| +The current NEON based ChaCha implementation for ARM is optimized for
 | |
| +multiples of 4x the ChaCha block size (64 bytes). This makes sense for
 | |
| +block encryption, but given that ChaCha is also often used in the
 | |
| +context of networking, it makes sense to consider arbitrary length
 | |
| +inputs as well.
 | |
| +
 | |
| +For example, WireGuard typically uses 1420 byte packets, and performing
 | |
| +ChaCha encryption involves 5 invocations of chacha_4block_xor_neon()
 | |
| +and 3 invocations of chacha_block_xor_neon(), where the last one also
 | |
| +involves a memcpy() using a buffer on the stack to process the final
 | |
| +chunk of 1420 % 64 == 12 bytes.
 | |
| +
 | |
| +Let's optimize for this case as well, by letting chacha_4block_xor_neon()
 | |
| +deal with any input size between 64 and 256 bytes, using NEON permutation
 | |
| +instructions and overlapping loads and stores. This way, the 140 byte
 | |
| +tail of a 1420 byte input buffer can simply be processed in one go.
 | |
| +
 | |
| +This results in the following performance improvements for 1420 byte
 | |
| +blocks, without significant impact on power-of-2 input sizes. (Note
 | |
| +that Raspberry Pi is widely used in combination with a 32-bit kernel,
 | |
| +even though the core is 64-bit capable)
 | |
| +
 | |
| +   Cortex-A8  (BeagleBone)       :   7%
 | |
| +   Cortex-A15 (Calxeda Midway)   :  21%
 | |
| +   Cortex-A53 (Raspberry Pi 3)   :   3%
 | |
| +   Cortex-A72 (Raspberry Pi 4)   :  19%
 | |
| +
 | |
| +Cc: Eric Biggers <ebiggers@google.com>
 | |
| +Cc: "Jason A . Donenfeld" <Jason@zx2c4.com>
 | |
| +Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
 | |
| +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
 | |
| +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
 | |
| +---
 | |
| + arch/arm/crypto/chacha-glue.c      | 34 +++++------
 | |
| + arch/arm/crypto/chacha-neon-core.S | 97 +++++++++++++++++++++++++++---
 | |
| + 2 files changed, 107 insertions(+), 24 deletions(-)
 | |
| +
 | |
| +--- a/arch/arm/crypto/chacha-glue.c
 | |
| ++++ b/arch/arm/crypto/chacha-glue.c
 | |
| +@@ -23,7 +23,7 @@
 | |
| + asmlinkage void chacha_block_xor_neon(const u32 *state, u8 *dst, const u8 *src,
 | |
| + 				      int nrounds);
 | |
| + asmlinkage void chacha_4block_xor_neon(const u32 *state, u8 *dst, const u8 *src,
 | |
| +-				       int nrounds);
 | |
| ++				       int nrounds, unsigned int nbytes);
 | |
| + asmlinkage void hchacha_block_arm(const u32 *state, u32 *out, int nrounds);
 | |
| + asmlinkage void hchacha_block_neon(const u32 *state, u32 *out, int nrounds);
 | |
| + 
 | |
| +@@ -42,24 +42,24 @@ static void chacha_doneon(u32 *state, u8
 | |
| + {
 | |
| + 	u8 buf[CHACHA_BLOCK_SIZE];
 | |
| + 
 | |
| +-	while (bytes >= CHACHA_BLOCK_SIZE * 4) {
 | |
| +-		chacha_4block_xor_neon(state, dst, src, nrounds);
 | |
| +-		bytes -= CHACHA_BLOCK_SIZE * 4;
 | |
| +-		src += CHACHA_BLOCK_SIZE * 4;
 | |
| +-		dst += CHACHA_BLOCK_SIZE * 4;
 | |
| +-		state[12] += 4;
 | |
| +-	}
 | |
| +-	while (bytes >= CHACHA_BLOCK_SIZE) {
 | |
| +-		chacha_block_xor_neon(state, dst, src, nrounds);
 | |
| +-		bytes -= CHACHA_BLOCK_SIZE;
 | |
| +-		src += CHACHA_BLOCK_SIZE;
 | |
| +-		dst += CHACHA_BLOCK_SIZE;
 | |
| +-		state[12]++;
 | |
| ++	while (bytes > CHACHA_BLOCK_SIZE) {
 | |
| ++		unsigned int l = min(bytes, CHACHA_BLOCK_SIZE * 4U);
 | |
| ++
 | |
| ++		chacha_4block_xor_neon(state, dst, src, nrounds, l);
 | |
| ++		bytes -= l;
 | |
| ++		src += l;
 | |
| ++		dst += l;
 | |
| ++		state[12] += DIV_ROUND_UP(l, CHACHA_BLOCK_SIZE);
 | |
| + 	}
 | |
| + 	if (bytes) {
 | |
| +-		memcpy(buf, src, bytes);
 | |
| +-		chacha_block_xor_neon(state, buf, buf, nrounds);
 | |
| +-		memcpy(dst, buf, bytes);
 | |
| ++		const u8 *s = src;
 | |
| ++		u8 *d = dst;
 | |
| ++
 | |
| ++		if (bytes != CHACHA_BLOCK_SIZE)
 | |
| ++			s = d = memcpy(buf, src, bytes);
 | |
| ++		chacha_block_xor_neon(state, d, s, nrounds);
 | |
| ++		if (d != dst)
 | |
| ++			memcpy(dst, buf, bytes);
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| +--- a/arch/arm/crypto/chacha-neon-core.S
 | |
| ++++ b/arch/arm/crypto/chacha-neon-core.S
 | |
| +@@ -47,6 +47,7 @@
 | |
| +   */
 | |
| + 
 | |
| + #include <linux/linkage.h>
 | |
| ++#include <asm/cache.h>
 | |
| + 
 | |
| + 	.text
 | |
| + 	.fpu		neon
 | |
| +@@ -205,7 +206,7 @@ ENDPROC(hchacha_block_neon)
 | |
| + 
 | |
| + 	.align		5
 | |
| + ENTRY(chacha_4block_xor_neon)
 | |
| +-	push		{r4-r5}
 | |
| ++	push		{r4, lr}
 | |
| + 	mov		r4, sp			// preserve the stack pointer
 | |
| + 	sub		ip, sp, #0x20		// allocate a 32 byte buffer
 | |
| + 	bic		ip, ip, #0x1f		// aligned to 32 bytes
 | |
| +@@ -229,10 +230,10 @@ ENTRY(chacha_4block_xor_neon)
 | |
| + 	vld1.32		{q0-q1}, [r0]
 | |
| + 	vld1.32		{q2-q3}, [ip]
 | |
| + 
 | |
| +-	adr		r5, .Lctrinc
 | |
| ++	adr		lr, .Lctrinc
 | |
| + 	vdup.32		q15, d7[1]
 | |
| + 	vdup.32		q14, d7[0]
 | |
| +-	vld1.32		{q4}, [r5, :128]
 | |
| ++	vld1.32		{q4}, [lr, :128]
 | |
| + 	vdup.32		q13, d6[1]
 | |
| + 	vdup.32		q12, d6[0]
 | |
| + 	vdup.32		q11, d5[1]
 | |
| +@@ -455,7 +456,7 @@ ENTRY(chacha_4block_xor_neon)
 | |
| + 
 | |
| + 	// Re-interleave the words in the first two rows of each block (x0..7).
 | |
| + 	// Also add the counter values 0-3 to x12[0-3].
 | |
| +-	  vld1.32	{q8}, [r5, :128]	// load counter values 0-3
 | |
| ++	  vld1.32	{q8}, [lr, :128]	// load counter values 0-3
 | |
| + 	vzip.32		q0, q1			// => (0 1 0 1) (0 1 0 1)
 | |
| + 	vzip.32		q2, q3			// => (2 3 2 3) (2 3 2 3)
 | |
| + 	vzip.32		q4, q5			// => (4 5 4 5) (4 5 4 5)
 | |
| +@@ -493,6 +494,8 @@ ENTRY(chacha_4block_xor_neon)
 | |
| + 
 | |
| + 	// Re-interleave the words in the last two rows of each block (x8..15).
 | |
| + 	vld1.32		{q8-q9}, [sp, :256]
 | |
| ++	  mov		sp, r4		// restore original stack pointer
 | |
| ++	  ldr		r4, [r4, #8]	// load number of bytes
 | |
| + 	vzip.32		q12, q13	// => (12 13 12 13) (12 13 12 13)
 | |
| + 	vzip.32		q14, q15	// => (14 15 14 15) (14 15 14 15)
 | |
| + 	vzip.32		q8, q9		// => (8 9 8 9) (8 9 8 9)
 | |
| +@@ -520,41 +523,121 @@ ENTRY(chacha_4block_xor_neon)
 | |
| + 	// XOR the rest of the data with the keystream
 | |
| + 
 | |
| + 	vld1.8		{q0-q1}, [r2]!
 | |
| ++	subs		r4, r4, #96
 | |
| + 	veor		q0, q0, q8
 | |
| + 	veor		q1, q1, q12
 | |
| ++	ble		.Lle96
 | |
| + 	vst1.8		{q0-q1}, [r1]!
 | |
| + 
 | |
| + 	vld1.8		{q0-q1}, [r2]!
 | |
| ++	subs		r4, r4, #32
 | |
| + 	veor		q0, q0, q2
 | |
| + 	veor		q1, q1, q6
 | |
| ++	ble		.Lle128
 | |
| + 	vst1.8		{q0-q1}, [r1]!
 | |
| + 
 | |
| + 	vld1.8		{q0-q1}, [r2]!
 | |
| ++	subs		r4, r4, #32
 | |
| + 	veor		q0, q0, q10
 | |
| + 	veor		q1, q1, q14
 | |
| ++	ble		.Lle160
 | |
| + 	vst1.8		{q0-q1}, [r1]!
 | |
| + 
 | |
| + 	vld1.8		{q0-q1}, [r2]!
 | |
| ++	subs		r4, r4, #32
 | |
| + 	veor		q0, q0, q4
 | |
| + 	veor		q1, q1, q5
 | |
| ++	ble		.Lle192
 | |
| + 	vst1.8		{q0-q1}, [r1]!
 | |
| + 
 | |
| + 	vld1.8		{q0-q1}, [r2]!
 | |
| ++	subs		r4, r4, #32
 | |
| + 	veor		q0, q0, q9
 | |
| + 	veor		q1, q1, q13
 | |
| ++	ble		.Lle224
 | |
| + 	vst1.8		{q0-q1}, [r1]!
 | |
| + 
 | |
| + 	vld1.8		{q0-q1}, [r2]!
 | |
| ++	subs		r4, r4, #32
 | |
| + 	veor		q0, q0, q3
 | |
| + 	veor		q1, q1, q7
 | |
| ++	blt		.Llt256
 | |
| ++.Lout:
 | |
| + 	vst1.8		{q0-q1}, [r1]!
 | |
| + 
 | |
| + 	vld1.8		{q0-q1}, [r2]
 | |
| +-	  mov		sp, r4		// restore original stack pointer
 | |
| + 	veor		q0, q0, q11
 | |
| + 	veor		q1, q1, q15
 | |
| + 	vst1.8		{q0-q1}, [r1]
 | |
| + 
 | |
| +-	pop		{r4-r5}
 | |
| +-	bx		lr
 | |
| ++	pop		{r4, pc}
 | |
| ++
 | |
| ++.Lle192:
 | |
| ++	vmov		q4, q9
 | |
| ++	vmov		q5, q13
 | |
| ++
 | |
| ++.Lle160:
 | |
| ++	// nothing to do
 | |
| ++
 | |
| ++.Lfinalblock:
 | |
| ++	// Process the final block if processing less than 4 full blocks.
 | |
| ++	// Entered with 32 bytes of ChaCha cipher stream in q4-q5, and the
 | |
| ++	// previous 32 byte output block that still needs to be written at
 | |
| ++	// [r1] in q0-q1.
 | |
| ++	beq		.Lfullblock
 | |
| ++
 | |
| ++.Lpartialblock:
 | |
| ++	adr		lr, .Lpermute + 32
 | |
| ++	add		r2, r2, r4
 | |
| ++	add		lr, lr, r4
 | |
| ++	add		r4, r4, r1
 | |
| ++
 | |
| ++	vld1.8		{q2-q3}, [lr]
 | |
| ++	vld1.8		{q6-q7}, [r2]
 | |
| ++
 | |
| ++	add		r4, r4, #32
 | |
| ++
 | |
| ++	vtbl.8		d4, {q4-q5}, d4
 | |
| ++	vtbl.8		d5, {q4-q5}, d5
 | |
| ++	vtbl.8		d6, {q4-q5}, d6
 | |
| ++	vtbl.8		d7, {q4-q5}, d7
 | |
| ++
 | |
| ++	veor		q6, q6, q2
 | |
| ++	veor		q7, q7, q3
 | |
| ++
 | |
| ++	vst1.8		{q6-q7}, [r4]	// overlapping stores
 | |
| ++	vst1.8		{q0-q1}, [r1]
 | |
| ++	pop		{r4, pc}
 | |
| ++
 | |
| ++.Lfullblock:
 | |
| ++	vmov		q11, q4
 | |
| ++	vmov		q15, q5
 | |
| ++	b		.Lout
 | |
| ++.Lle96:
 | |
| ++	vmov		q4, q2
 | |
| ++	vmov		q5, q6
 | |
| ++	b		.Lfinalblock
 | |
| ++.Lle128:
 | |
| ++	vmov		q4, q10
 | |
| ++	vmov		q5, q14
 | |
| ++	b		.Lfinalblock
 | |
| ++.Lle224:
 | |
| ++	vmov		q4, q3
 | |
| ++	vmov		q5, q7
 | |
| ++	b		.Lfinalblock
 | |
| ++.Llt256:
 | |
| ++	vmov		q4, q11
 | |
| ++	vmov		q5, q15
 | |
| ++	b		.Lpartialblock
 | |
| + ENDPROC(chacha_4block_xor_neon)
 | |
| ++
 | |
| ++	.align		L1_CACHE_SHIFT
 | |
| ++.Lpermute:
 | |
| ++	.byte		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
 | |
| ++	.byte		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
 | |
| ++	.byte		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
 | |
| ++	.byte		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
 | |
| ++	.byte		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
 | |
| ++	.byte		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
 | |
| ++	.byte		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
 | |
| ++	.byte		0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
 | |
| diff --git a/target/linux/generic/backport-5.10/072-crypto-arm-chacha-neon-add-missing-counter-increment.patch b/target/linux/generic/backport-5.10/072-crypto-arm-chacha-neon-add-missing-counter-increment.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1e4d2041e5
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/072-crypto-arm-chacha-neon-add-missing-counter-increment.patch
 | |
| @@ -0,0 +1,38 @@
 | |
| +From 7f63462faf9eab69132bea9abd48c2c05a93145b Mon Sep 17 00:00:00 2001
 | |
| +From: Ard Biesheuvel <ardb@kernel.org>
 | |
| +Date: Sun, 13 Dec 2020 15:39:29 +0100
 | |
| +Subject: [PATCH 2/2] crypto: arm/chacha-neon - add missing counter increment
 | |
| +
 | |
| +commit fd16931a2f518a32753920ff20895e5cf04c8ff1 upstream.
 | |
| +
 | |
| +Commit 86cd97ec4b943af3 ("crypto: arm/chacha-neon - optimize for non-block
 | |
| +size multiples") refactored the chacha block handling in the glue code in
 | |
| +a way that may result in the counter increment to be omitted when calling
 | |
| +chacha_block_xor_neon() to process a full block. This violates the skcipher
 | |
| +API, which requires that the output IV is suitable for handling more input
 | |
| +as long as the preceding input has been presented in round multiples of the
 | |
| +block size. Also, the same code is exposed via the chacha library interface
 | |
| +whose callers may actually rely on this increment to occur even for final
 | |
| +blocks that are smaller than the chacha block size.
 | |
| +
 | |
| +So increment the counter after calling chacha_block_xor_neon().
 | |
| +
 | |
| +Fixes: 86cd97ec4b943af3 ("crypto: arm/chacha-neon - optimize for non-block size multiples")
 | |
| +Reported-by: Eric Biggers <ebiggers@kernel.org>
 | |
| +Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
 | |
| +Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
 | |
| +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
 | |
| +---
 | |
| + arch/arm/crypto/chacha-glue.c | 1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/arch/arm/crypto/chacha-glue.c
 | |
| ++++ b/arch/arm/crypto/chacha-glue.c
 | |
| +@@ -60,6 +60,7 @@ static void chacha_doneon(u32 *state, u8
 | |
| + 		chacha_block_xor_neon(state, d, s, nrounds);
 | |
| + 		if (d != dst)
 | |
| + 			memcpy(dst, buf, bytes);
 | |
| ++		state[12]++;
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| diff --git a/target/linux/generic/backport-5.10/080-wireguard-peer-put-frequently-used-members-above-cac.patch b/target/linux/generic/backport-5.10/080-wireguard-peer-put-frequently-used-members-above-cac.patch
 | |
| new file mode 100644
 | |
| index 0000000000..444fd677b4
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/080-wireguard-peer-put-frequently-used-members-above-cac.patch
 | |
| @@ -0,0 +1,42 @@
 | |
| +From a13827e9091c07e25cdeec9a402d74a27e2a1111 Mon Sep 17 00:00:00 2001
 | |
| +From: "Jason A. Donenfeld" <Jason@zx2c4.com>
 | |
| +Date: Mon, 22 Feb 2021 17:25:46 +0100
 | |
| +Subject: [PATCH] wireguard: peer: put frequently used members above cache
 | |
| + lines
 | |
| +
 | |
| +commit 5a0598695634a6bb4126818902dd9140cd9df8b6 upstream.
 | |
| +
 | |
| +The is_dead boolean is checked for every single packet, while the
 | |
| +internal_id member is used basically only for pr_debug messages. So it
 | |
| +makes sense to hoist up is_dead into some space formerly unused by a
 | |
| +struct hole, while demoting internal_api to below the lowest struct
 | |
| +cache line.
 | |
| +
 | |
| +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
 | |
| +---
 | |
| + drivers/net/wireguard/peer.h | 4 ++--
 | |
| + 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| +
 | |
| +--- a/drivers/net/wireguard/peer.h
 | |
| ++++ b/drivers/net/wireguard/peer.h
 | |
| +@@ -39,6 +39,7 @@ struct wg_peer {
 | |
| + 	struct prev_queue tx_queue, rx_queue;
 | |
| + 	struct sk_buff_head staged_packet_queue;
 | |
| + 	int serial_work_cpu;
 | |
| ++	bool is_dead;
 | |
| + 	struct noise_keypairs keypairs;
 | |
| + 	struct endpoint endpoint;
 | |
| + 	struct dst_cache endpoint_cache;
 | |
| +@@ -61,9 +62,8 @@ struct wg_peer {
 | |
| + 	struct rcu_head rcu;
 | |
| + 	struct list_head peer_list;
 | |
| + 	struct list_head allowedips_list;
 | |
| +-	u64 internal_id;
 | |
| + 	struct napi_struct napi;
 | |
| +-	bool is_dead;
 | |
| ++	u64 internal_id;
 | |
| + };
 | |
| + 
 | |
| + struct wg_peer *wg_peer_create(struct wg_device *wg,
 | |
| diff --git a/target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch b/target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
 | |
| new file mode 100644
 | |
| index 0000000000..137264cb9f
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/343-netfilter-nft_flow_offload-handle-netdevice-events-f.patch
 | |
| @@ -0,0 +1,106 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Thu, 25 Jan 2018 12:58:55 +0100
 | |
| +Subject: [PATCH] netfilter: nft_flow_offload: handle netdevice events from
 | |
| + nf_flow_table
 | |
| +
 | |
| +Move the code that deals with device events to the core.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -577,13 +577,41 @@ void nf_flow_table_free(struct nf_flowta
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(nf_flow_table_free);
 | |
| + 
 | |
| ++static int nf_flow_table_netdev_event(struct notifier_block *this,
 | |
| ++				      unsigned long event, void *ptr)
 | |
| ++{
 | |
| ++	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 | |
| ++
 | |
| ++	if (event != NETDEV_DOWN)
 | |
| ++		return NOTIFY_DONE;
 | |
| ++
 | |
| ++	nf_flow_table_cleanup(dev);
 | |
| ++
 | |
| ++	return NOTIFY_DONE;
 | |
| ++}
 | |
| ++
 | |
| ++static struct notifier_block flow_offload_netdev_notifier = {
 | |
| ++	.notifier_call	= nf_flow_table_netdev_event,
 | |
| ++};
 | |
| ++
 | |
| + static int __init nf_flow_table_module_init(void)
 | |
| + {
 | |
| +-	return nf_flow_table_offload_init();
 | |
| ++	int ret;
 | |
| ++
 | |
| ++	ret = nf_flow_table_offload_init();
 | |
| ++	if (ret)
 | |
| ++		return ret;
 | |
| ++
 | |
| ++	ret = register_netdevice_notifier(&flow_offload_netdev_notifier);
 | |
| ++	if (ret)
 | |
| ++		nf_flow_table_offload_exit();
 | |
| ++
 | |
| ++	return ret;
 | |
| + }
 | |
| + 
 | |
| + static void __exit nf_flow_table_module_exit(void)
 | |
| + {
 | |
| ++	unregister_netdevice_notifier(&flow_offload_netdev_notifier);
 | |
| + 	nf_flow_table_offload_exit();
 | |
| + }
 | |
| + 
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -237,47 +237,14 @@ static struct nft_expr_type nft_flow_off
 | |
| + 	.owner		= THIS_MODULE,
 | |
| + };
 | |
| + 
 | |
| +-static int flow_offload_netdev_event(struct notifier_block *this,
 | |
| +-				     unsigned long event, void *ptr)
 | |
| +-{
 | |
| +-	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 | |
| +-
 | |
| +-	if (event != NETDEV_DOWN)
 | |
| +-		return NOTIFY_DONE;
 | |
| +-
 | |
| +-	nf_flow_table_cleanup(dev);
 | |
| +-
 | |
| +-	return NOTIFY_DONE;
 | |
| +-}
 | |
| +-
 | |
| +-static struct notifier_block flow_offload_netdev_notifier = {
 | |
| +-	.notifier_call	= flow_offload_netdev_event,
 | |
| +-};
 | |
| +-
 | |
| + static int __init nft_flow_offload_module_init(void)
 | |
| + {
 | |
| +-	int err;
 | |
| +-
 | |
| +-	err = register_netdevice_notifier(&flow_offload_netdev_notifier);
 | |
| +-	if (err)
 | |
| +-		goto err;
 | |
| +-
 | |
| +-	err = nft_register_expr(&nft_flow_offload_type);
 | |
| +-	if (err < 0)
 | |
| +-		goto register_expr;
 | |
| +-
 | |
| +-	return 0;
 | |
| +-
 | |
| +-register_expr:
 | |
| +-	unregister_netdevice_notifier(&flow_offload_netdev_notifier);
 | |
| +-err:
 | |
| +-	return err;
 | |
| ++	return nft_register_expr(&nft_flow_offload_type);
 | |
| + }
 | |
| + 
 | |
| + static void __exit nft_flow_offload_module_exit(void)
 | |
| + {
 | |
| + 	nft_unregister_expr(&nft_flow_offload_type);
 | |
| +-	unregister_netdevice_notifier(&flow_offload_netdev_notifier);
 | |
| + }
 | |
| + 
 | |
| + module_init(nft_flow_offload_module_init);
 | |
| diff --git a/target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch b/target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch
 | |
| new file mode 100644
 | |
| index 0000000000..8aded43526
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/401-v5.11-dt-bindings-mtd-convert-fixed-partitions-to-the-json.patch
 | |
| @@ -0,0 +1,324 @@
 | |
| +From 04e9ab75267489224364fa510a88ada83e11c325 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Thu, 10 Dec 2020 18:23:52 +0100
 | |
| +Subject: [PATCH] dt-bindings: mtd: convert "fixed-partitions" to the
 | |
| + json-schema
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This standardizes its documentation, allows validating with Makefile
 | |
| +checks and helps writing DTS files.
 | |
| +
 | |
| +Noticeable changes:
 | |
| +1. Dropped "Partitions can be represented by sub-nodes of a flash
 | |
| +   device." as we also support subpartitions (don't have to be part of
 | |
| +   flash device node)
 | |
| +2. Dropped "to Linux" as bindings are meant to be os agnostic.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Link: https://lore.kernel.org/r/20201210172352.31632-1-zajec5@gmail.com
 | |
| +Signed-off-by: Rob Herring <robh@kernel.org>
 | |
| +---
 | |
| + .../devicetree/bindings/mtd/partition.txt     | 131 +--------------
 | |
| + .../mtd/partitions/fixed-partitions.yaml      | 152 ++++++++++++++++++
 | |
| + 2 files changed, 154 insertions(+), 129 deletions(-)
 | |
| + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
 | |
| +
 | |
| +--- a/Documentation/devicetree/bindings/mtd/partition.txt
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/partition.txt
 | |
| +@@ -24,137 +24,10 @@ another partitioning method.
 | |
| + Available bindings are listed in the "partitions" subdirectory.
 | |
| + 
 | |
| + 
 | |
| +-Fixed Partitions
 | |
| +-================
 | |
| +-
 | |
| +-Partitions can be represented by sub-nodes of a flash device. This can be used
 | |
| +-on platforms which have strong conventions about which portions of a flash are
 | |
| +-used for what purposes, but which don't use an on-flash partition table such
 | |
| +-as RedBoot.
 | |
| +-
 | |
| +-The partition table should be a subnode of the flash node and should be named
 | |
| +-'partitions'. This node should have the following property:
 | |
| +-- compatible : (required) must be "fixed-partitions"
 | |
| +-Partitions are then defined in subnodes of the partitions node.
 | |
| ++Deprecated: partitions defined in flash node
 | |
| ++============================================
 | |
| + 
 | |
| + For backwards compatibility partitions as direct subnodes of the flash device are
 | |
| + supported. This use is discouraged.
 | |
| + NOTE: also for backwards compatibility, direct subnodes that have a compatible
 | |
| + string are not considered partitions, as they may be used for other bindings.
 | |
| +-
 | |
| +-#address-cells & #size-cells must both be present in the partitions subnode of the
 | |
| +-flash device. There are two valid values for both:
 | |
| +-<1>: for partitions that require a single 32-bit cell to represent their
 | |
| +-     size/address (aka the value is below 4 GiB)
 | |
| +-<2>: for partitions that require two 32-bit cells to represent their
 | |
| +-     size/address (aka the value is 4 GiB or greater).
 | |
| +-
 | |
| +-Required properties:
 | |
| +-- reg : The partition's offset and size within the flash
 | |
| +-
 | |
| +-Optional properties:
 | |
| +-- label : The label / name for this partition.  If omitted, the label is taken
 | |
| +-  from the node name (excluding the unit address).
 | |
| +-- read-only : This parameter, if present, is a hint to Linux that this
 | |
| +-  partition should only be mounted read-only. This is usually used for flash
 | |
| +-  partitions containing early-boot firmware images or data which should not be
 | |
| +-  clobbered.
 | |
| +-- lock : Do not unlock the partition at initialization time (not supported on
 | |
| +-  all devices)
 | |
| +-- slc-mode: This parameter, if present, allows one to emulate SLC mode on a
 | |
| +-  partition attached to an MLC NAND thus making this partition immune to
 | |
| +-  paired-pages corruptions
 | |
| +-
 | |
| +-Examples:
 | |
| +-
 | |
| +-
 | |
| +-flash@0 {
 | |
| +-	partitions {
 | |
| +-		compatible = "fixed-partitions";
 | |
| +-		#address-cells = <1>;
 | |
| +-		#size-cells = <1>;
 | |
| +-
 | |
| +-		partition@0 {
 | |
| +-			label = "u-boot";
 | |
| +-			reg = <0x0000000 0x100000>;
 | |
| +-			read-only;
 | |
| +-		};
 | |
| +-
 | |
| +-		uimage@100000 {
 | |
| +-			reg = <0x0100000 0x200000>;
 | |
| +-		};
 | |
| +-	};
 | |
| +-};
 | |
| +-
 | |
| +-flash@1 {
 | |
| +-	partitions {
 | |
| +-		compatible = "fixed-partitions";
 | |
| +-		#address-cells = <1>;
 | |
| +-		#size-cells = <2>;
 | |
| +-
 | |
| +-		/* a 4 GiB partition */
 | |
| +-		partition@0 {
 | |
| +-			label = "filesystem";
 | |
| +-			reg = <0x00000000 0x1 0x00000000>;
 | |
| +-		};
 | |
| +-	};
 | |
| +-};
 | |
| +-
 | |
| +-flash@2 {
 | |
| +-	partitions {
 | |
| +-		compatible = "fixed-partitions";
 | |
| +-		#address-cells = <2>;
 | |
| +-		#size-cells = <2>;
 | |
| +-
 | |
| +-		/* an 8 GiB partition */
 | |
| +-		partition@0 {
 | |
| +-			label = "filesystem #1";
 | |
| +-			reg = <0x0 0x00000000 0x2 0x00000000>;
 | |
| +-		};
 | |
| +-
 | |
| +-		/* a 4 GiB partition */
 | |
| +-		partition@200000000 {
 | |
| +-			label = "filesystem #2";
 | |
| +-			reg = <0x2 0x00000000 0x1 0x00000000>;
 | |
| +-		};
 | |
| +-	};
 | |
| +-};
 | |
| +-
 | |
| +-flash@3 {
 | |
| +-	partitions {
 | |
| +-		compatible = "fixed-partitions";
 | |
| +-		#address-cells = <1>;
 | |
| +-		#size-cells = <1>;
 | |
| +-
 | |
| +-		partition@0 {
 | |
| +-			label = "bootloader";
 | |
| +-			reg = <0x000000 0x100000>;
 | |
| +-			read-only;
 | |
| +-		};
 | |
| +-
 | |
| +-		firmware@100000 {
 | |
| +-			label = "firmware";
 | |
| +-			reg = <0x100000 0xe00000>;
 | |
| +-			compatible = "brcm,trx";
 | |
| +-		};
 | |
| +-
 | |
| +-		calibration@f00000 {
 | |
| +-			label = "calibration";
 | |
| +-			reg = <0xf00000 0x100000>;
 | |
| +-			compatible = "fixed-partitions";
 | |
| +-			ranges = <0 0xf00000 0x100000>;
 | |
| +-			#address-cells = <1>;
 | |
| +-			#size-cells = <1>;
 | |
| +-
 | |
| +-			partition@0 {
 | |
| +-				label = "wifi0";
 | |
| +-				reg = <0x000000 0x080000>;
 | |
| +-			};
 | |
| +-
 | |
| +-			partition@80000 {
 | |
| +-				label = "wifi1";
 | |
| +-				reg = <0x080000 0x080000>;
 | |
| +-			};
 | |
| +-		};
 | |
| +-	};
 | |
| +-};
 | |
| +--- /dev/null
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
 | |
| +@@ -0,0 +1,152 @@
 | |
| ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | |
| ++%YAML 1.2
 | |
| ++---
 | |
| ++$id: http://devicetree.org/schemas/mtd/partitions/fixed-partitions.yaml#
 | |
| ++$schema: http://devicetree.org/meta-schemas/core.yaml#
 | |
| ++
 | |
| ++title: Fixed partitions
 | |
| ++
 | |
| ++description: |
 | |
| ++  This binding can be used on platforms which have strong conventions about
 | |
| ++  which portions of a flash are used for what purposes, but which don't use an
 | |
| ++  on-flash partition table such as RedBoot.
 | |
| ++
 | |
| ++  The partition table should be a node named "partitions". Partitions are then
 | |
| ++  defined as subnodes.
 | |
| ++
 | |
| ++maintainers:
 | |
| ++  - Rafał Miłecki <rafal@milecki.pl>
 | |
| ++
 | |
| ++properties:
 | |
| ++  compatible:
 | |
| ++    const: fixed-partitions
 | |
| ++
 | |
| ++  "#address-cells": true
 | |
| ++
 | |
| ++  "#size-cells": true
 | |
| ++
 | |
| ++patternProperties:
 | |
| ++  "@[0-9a-f]+$":
 | |
| ++    description: node describing a single flash partition
 | |
| ++    type: object
 | |
| ++
 | |
| ++    properties:
 | |
| ++      reg:
 | |
| ++        description: partition's offset and size within the flash
 | |
| ++        maxItems: 1
 | |
| ++
 | |
| ++      label:
 | |
| ++        description: The label / name for this partition. If omitted, the label
 | |
| ++          is taken from the node name (excluding the unit address).
 | |
| ++
 | |
| ++      read-only:
 | |
| ++        description: This parameter, if present, is a hint that this partition
 | |
| ++          should only be mounted read-only. This is usually used for flash
 | |
| ++          partitions containing early-boot firmware images or data which should
 | |
| ++          not be clobbered.
 | |
| ++        type: boolean
 | |
| ++
 | |
| ++      lock:
 | |
| ++        description: Do not unlock the partition at initialization time (not
 | |
| ++          supported on all devices)
 | |
| ++        type: boolean
 | |
| ++
 | |
| ++      slc-mode:
 | |
| ++        description: This parameter, if present, allows one to emulate SLC mode
 | |
| ++          on a partition attached to an MLC NAND thus making this partition
 | |
| ++          immune to paired-pages corruptions
 | |
| ++        type: boolean
 | |
| ++
 | |
| ++    required:
 | |
| ++      - reg
 | |
| ++
 | |
| ++required:
 | |
| ++  - "#address-cells"
 | |
| ++  - "#size-cells"
 | |
| ++
 | |
| ++additionalProperties: true
 | |
| ++
 | |
| ++examples:
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++        compatible = "fixed-partitions";
 | |
| ++        #address-cells = <1>;
 | |
| ++        #size-cells = <1>;
 | |
| ++
 | |
| ++        partition@0 {
 | |
| ++            label = "u-boot";
 | |
| ++            reg = <0x0000000 0x100000>;
 | |
| ++            read-only;
 | |
| ++        };
 | |
| ++
 | |
| ++        uimage@100000 {
 | |
| ++            reg = <0x0100000 0x200000>;
 | |
| ++        };
 | |
| ++    };
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++        compatible = "fixed-partitions";
 | |
| ++        #address-cells = <1>;
 | |
| ++        #size-cells = <2>;
 | |
| ++
 | |
| ++        /* a 4 GiB partition */
 | |
| ++        partition@0 {
 | |
| ++            label = "filesystem";
 | |
| ++            reg = <0x00000000 0x1 0x00000000>;
 | |
| ++        };
 | |
| ++    };
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++        compatible = "fixed-partitions";
 | |
| ++        #address-cells = <2>;
 | |
| ++        #size-cells = <2>;
 | |
| ++
 | |
| ++        /* an 8 GiB partition */
 | |
| ++        partition@0 {
 | |
| ++            label = "filesystem #1";
 | |
| ++            reg = <0x0 0x00000000 0x2 0x00000000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        /* a 4 GiB partition */
 | |
| ++        partition@200000000 {
 | |
| ++            label = "filesystem #2";
 | |
| ++            reg = <0x2 0x00000000 0x1 0x00000000>;
 | |
| ++        };
 | |
| ++    };
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++        compatible = "fixed-partitions";
 | |
| ++        #address-cells = <1>;
 | |
| ++        #size-cells = <1>;
 | |
| ++
 | |
| ++        partition@0 {
 | |
| ++            label = "bootloader";
 | |
| ++            reg = <0x000000 0x100000>;
 | |
| ++            read-only;
 | |
| ++        };
 | |
| ++
 | |
| ++        firmware@100000 {
 | |
| ++            compatible = "brcm,trx";
 | |
| ++            label = "firmware";
 | |
| ++            reg = <0x100000 0xe00000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        calibration@f00000 {
 | |
| ++            compatible = "fixed-partitions";
 | |
| ++            label = "calibration";
 | |
| ++            reg = <0xf00000 0x100000>;
 | |
| ++            ranges = <0 0xf00000 0x100000>;
 | |
| ++            #address-cells = <1>;
 | |
| ++            #size-cells = <1>;
 | |
| ++
 | |
| ++            partition@0 {
 | |
| ++                label = "wifi0";
 | |
| ++                reg = <0x000000 0x080000>;
 | |
| ++            };
 | |
| ++
 | |
| ++            partition@80000 {
 | |
| ++                label = "wifi1";
 | |
| ++                reg = <0x080000 0x080000>;
 | |
| ++            };
 | |
| ++        };
 | |
| ++    };
 | |
| diff --git a/target/linux/generic/backport-5.10/402-v5.12-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch b/target/linux/generic/backport-5.10/402-v5.12-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch
 | |
| new file mode 100644
 | |
| index 0000000000..f3b1179ecd
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/402-v5.12-0001-dt-bindings-mtd-move-partition-binding-to-its-own-fi.patch
 | |
| @@ -0,0 +1,115 @@
 | |
| +From 6418522022c706fd867b00b2571edba48b8fa8c7 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Thu, 11 Feb 2021 23:04:25 +0100
 | |
| +Subject: [PATCH] dt-bindings: mtd: move partition binding to its own file
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +Single partition binding is quite common and may be:
 | |
| +1. Used by multiple parsers
 | |
| +2. Extended for more specific cases
 | |
| +
 | |
| +Move it to separated file to avoid code duplication.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Reviewed-by: Rob Herring <robh@kernel.org>
 | |
| +Signed-off-by: Richard Weinberger <richard@nod.at>
 | |
| +---
 | |
| + .../mtd/partitions/fixed-partitions.yaml      | 33 +------------
 | |
| + .../bindings/mtd/partitions/partition.yaml    | 47 +++++++++++++++++++
 | |
| + 2 files changed, 48 insertions(+), 32 deletions(-)
 | |
| + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/partition.yaml
 | |
| +
 | |
| +--- a/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/partitions/fixed-partitions.yaml
 | |
| +@@ -27,38 +27,7 @@ properties:
 | |
| + 
 | |
| + patternProperties:
 | |
| +   "@[0-9a-f]+$":
 | |
| +-    description: node describing a single flash partition
 | |
| +-    type: object
 | |
| +-
 | |
| +-    properties:
 | |
| +-      reg:
 | |
| +-        description: partition's offset and size within the flash
 | |
| +-        maxItems: 1
 | |
| +-
 | |
| +-      label:
 | |
| +-        description: The label / name for this partition. If omitted, the label
 | |
| +-          is taken from the node name (excluding the unit address).
 | |
| +-
 | |
| +-      read-only:
 | |
| +-        description: This parameter, if present, is a hint that this partition
 | |
| +-          should only be mounted read-only. This is usually used for flash
 | |
| +-          partitions containing early-boot firmware images or data which should
 | |
| +-          not be clobbered.
 | |
| +-        type: boolean
 | |
| +-
 | |
| +-      lock:
 | |
| +-        description: Do not unlock the partition at initialization time (not
 | |
| +-          supported on all devices)
 | |
| +-        type: boolean
 | |
| +-
 | |
| +-      slc-mode:
 | |
| +-        description: This parameter, if present, allows one to emulate SLC mode
 | |
| +-          on a partition attached to an MLC NAND thus making this partition
 | |
| +-          immune to paired-pages corruptions
 | |
| +-        type: boolean
 | |
| +-
 | |
| +-    required:
 | |
| +-      - reg
 | |
| ++    $ref: "partition.yaml#"
 | |
| + 
 | |
| + required:
 | |
| +   - "#address-cells"
 | |
| +--- /dev/null
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/partitions/partition.yaml
 | |
| +@@ -0,0 +1,47 @@
 | |
| ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | |
| ++%YAML 1.2
 | |
| ++---
 | |
| ++$id: http://devicetree.org/schemas/mtd/partitions/partition.yaml#
 | |
| ++$schema: http://devicetree.org/meta-schemas/core.yaml#
 | |
| ++
 | |
| ++title: Partition
 | |
| ++
 | |
| ++description: |
 | |
| ++  This binding describes a single flash partition. Each partition must have its
 | |
| ++  relative offset and size specified. Depending on partition function extra
 | |
| ++  properties can be used.
 | |
| ++
 | |
| ++maintainers:
 | |
| ++  - Rafał Miłecki <rafal@milecki.pl>
 | |
| ++
 | |
| ++properties:
 | |
| ++  reg:
 | |
| ++    description: partition's offset and size within the flash
 | |
| ++    maxItems: 1
 | |
| ++
 | |
| ++  label:
 | |
| ++    description: The label / name for this partition. If omitted, the label
 | |
| ++      is taken from the node name (excluding the unit address).
 | |
| ++
 | |
| ++  read-only:
 | |
| ++    description: This parameter, if present, is a hint that this partition
 | |
| ++      should only be mounted read-only. This is usually used for flash
 | |
| ++      partitions containing early-boot firmware images or data which should
 | |
| ++      not be clobbered.
 | |
| ++    type: boolean
 | |
| ++
 | |
| ++  lock:
 | |
| ++    description: Do not unlock the partition at initialization time (not
 | |
| ++      supported on all devices)
 | |
| ++    type: boolean
 | |
| ++
 | |
| ++  slc-mode:
 | |
| ++    description: This parameter, if present, allows one to emulate SLC mode
 | |
| ++      on a partition attached to an MLC NAND thus making this partition
 | |
| ++      immune to paired-pages corruptions
 | |
| ++    type: boolean
 | |
| ++
 | |
| ++required:
 | |
| ++  - reg
 | |
| ++
 | |
| ++additionalProperties: true
 | |
| diff --git a/target/linux/generic/backport-5.10/402-v5.12-0002-dt-bindings-mtd-add-binding-for-BCM4908-partitions.patch b/target/linux/generic/backport-5.10/402-v5.12-0002-dt-bindings-mtd-add-binding-for-BCM4908-partitions.patch
 | |
| new file mode 100644
 | |
| index 0000000000..8576c7d78d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/402-v5.12-0002-dt-bindings-mtd-add-binding-for-BCM4908-partitions.patch
 | |
| @@ -0,0 +1,92 @@
 | |
| +From 6e9dff6fe3fbc452f16566e4a7e293b0decefdba Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Thu, 11 Feb 2021 23:04:26 +0100
 | |
| +Subject: [PATCH] dt-bindings: mtd: add binding for BCM4908 partitions
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +BCM4908 uses fixed partitions layout but function of some partitions may
 | |
| +vary. Some devices use multiple firmware partitions and those partitions
 | |
| +should be marked to let system discover their purpose.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Richard Weinberger <richard@nod.at>
 | |
| +---
 | |
| + .../partitions/brcm,bcm4908-partitions.yaml   | 70 +++++++++++++++++++
 | |
| + 1 file changed, 70 insertions(+)
 | |
| + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
 | |
| +
 | |
| +--- /dev/null
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm4908-partitions.yaml
 | |
| +@@ -0,0 +1,70 @@
 | |
| ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | |
| ++%YAML 1.2
 | |
| ++---
 | |
| ++$id: http://devicetree.org/schemas/mtd/partitions/brcm,bcm4908-partitions.yaml#
 | |
| ++$schema: http://devicetree.org/meta-schemas/core.yaml#
 | |
| ++
 | |
| ++title: Broadcom BCM4908 partitioning
 | |
| ++
 | |
| ++description: |
 | |
| ++  Broadcom BCM4908 CFE bootloader supports two firmware partitions. One is used
 | |
| ++  for regular booting, the other is treated as fallback.
 | |
| ++
 | |
| ++  This binding allows defining all fixed partitions and marking those containing
 | |
| ++  firmware. System can use that information e.g. for booting or flashing
 | |
| ++  purposes.
 | |
| ++
 | |
| ++maintainers:
 | |
| ++  - Rafał Miłecki <rafal@milecki.pl>
 | |
| ++
 | |
| ++properties:
 | |
| ++  compatible:
 | |
| ++    const: brcm,bcm4908-partitions
 | |
| ++
 | |
| ++  "#address-cells":
 | |
| ++    enum: [ 1, 2 ]
 | |
| ++
 | |
| ++  "#size-cells":
 | |
| ++    enum: [ 1, 2 ]
 | |
| ++
 | |
| ++patternProperties:
 | |
| ++  "^partition@[0-9a-f]+$":
 | |
| ++    $ref: "partition.yaml#"
 | |
| ++    properties:
 | |
| ++      compatible:
 | |
| ++        const: brcm,bcm4908-firmware
 | |
| ++    unevaluatedProperties: false
 | |
| ++
 | |
| ++required:
 | |
| ++  - "#address-cells"
 | |
| ++  - "#size-cells"
 | |
| ++
 | |
| ++additionalProperties: false
 | |
| ++
 | |
| ++examples:
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++        compatible = "brcm,bcm4908-partitions";
 | |
| ++        #address-cells = <1>;
 | |
| ++        #size-cells = <1>;
 | |
| ++
 | |
| ++        partition@0 {
 | |
| ++            label = "cferom";
 | |
| ++            reg = <0x0 0x100000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        partition@100000 {
 | |
| ++            compatible = "brcm,bcm4908-firmware";
 | |
| ++            reg = <0x100000 0xf00000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        partition@1000000 {
 | |
| ++            compatible = "brcm,bcm4908-firmware";
 | |
| ++            reg = <0x1000000 0xf00000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        partition@1f00000 {
 | |
| ++            label = "calibration";
 | |
| ++            reg = <0x1f00000 0x100000>;
 | |
| ++        };
 | |
| ++    };
 | |
| diff --git a/target/linux/generic/backport-5.10/403-v5.13-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch b/target/linux/generic/backport-5.10/403-v5.13-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch
 | |
| new file mode 100644
 | |
| index 0000000000..d3891228e2
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/403-v5.13-mtd-parsers-ofpart-support-BCM4908-fixed-partitions.patch
 | |
| @@ -0,0 +1,654 @@
 | |
| +From afbef8efb591792579c633a7c545f914c6165f82 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Thu, 11 Feb 2021 23:04:27 +0100
 | |
| +Subject: [PATCH] mtd: parsers: ofpart: support BCM4908 fixed partitions
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +Some devices use fixed partitioning with some partitions requiring some
 | |
| +extra logic. E.g. BCM4908 may have multiple firmware partitions but
 | |
| +detecting currently used one requires checking bootloader parameters.
 | |
| +
 | |
| +To support such cases without duplicating a lot of code (without copying
 | |
| +most of the ofpart.c code) support for post-parsing callback was added.
 | |
| +
 | |
| +BCM4908 support in ofpart can be enabled using config option and results
 | |
| +in compiling & executing a specific callback. It simply reads offset of
 | |
| +currently used firmware partition from the DT. Bootloader specifies it
 | |
| +using the "brcm_blparms" property.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +---
 | |
| + drivers/mtd/parsers/Kconfig                   |  9 +++
 | |
| + drivers/mtd/parsers/Makefile                  |  2 +
 | |
| + drivers/mtd/parsers/ofpart_bcm4908.c          | 64 +++++++++++++++++++
 | |
| + drivers/mtd/parsers/ofpart_bcm4908.h          | 15 +++++
 | |
| + .../mtd/parsers/{ofpart.c => ofpart_core.c}   | 28 +++++++-
 | |
| + 5 files changed, 116 insertions(+), 2 deletions(-)
 | |
| + create mode 100644 drivers/mtd/parsers/ofpart_bcm4908.c
 | |
| + create mode 100644 drivers/mtd/parsers/ofpart_bcm4908.h
 | |
| + rename drivers/mtd/parsers/{ofpart.c => ofpart_core.c} (88%)
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/Kconfig
 | |
| ++++ b/drivers/mtd/parsers/Kconfig
 | |
| +@@ -67,6 +67,15 @@ config MTD_OF_PARTS
 | |
| + 	  flash memory node, as described in
 | |
| + 	  Documentation/devicetree/bindings/mtd/partition.txt.
 | |
| + 
 | |
| ++config MTD_OF_PARTS_BCM4908
 | |
| ++	bool "BCM4908 partitioning support"
 | |
| ++	depends on MTD_OF_PARTS && (ARCH_BCM4908 || COMPILE_TEST)
 | |
| ++	default ARCH_BCM4908
 | |
| ++	help
 | |
| ++	  This provides partitions parser for BCM4908 family devices
 | |
| ++	  that can have multiple "firmware" partitions. It takes care of
 | |
| ++	  finding currently used one and backup ones.
 | |
| ++
 | |
| + config MTD_PARSER_IMAGETAG
 | |
| + 	tristate "Parser for BCM963XX Image Tag format partitions"
 | |
| + 	depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
 | |
| +--- a/drivers/mtd/parsers/Makefile
 | |
| ++++ b/drivers/mtd/parsers/Makefile
 | |
| +@@ -4,6 +4,8 @@ obj-$(CONFIG_MTD_BCM47XX_PARTS)		+= bcm4
 | |
| + obj-$(CONFIG_MTD_BCM63XX_PARTS)		+= bcm63xxpart.o
 | |
| + obj-$(CONFIG_MTD_CMDLINE_PARTS)		+= cmdlinepart.o
 | |
| + obj-$(CONFIG_MTD_OF_PARTS)		+= ofpart.o
 | |
| ++ofpart-y				+= ofpart_core.o
 | |
| ++ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908)	+= ofpart_bcm4908.o
 | |
| + obj-$(CONFIG_MTD_PARSER_IMAGETAG)	+= parser_imagetag.o
 | |
| + obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o
 | |
| + obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/parsers/ofpart_bcm4908.c
 | |
| +@@ -0,0 +1,64 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0
 | |
| ++/*
 | |
| ++ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
 | |
| ++ */
 | |
| ++
 | |
| ++#include <linux/module.h>
 | |
| ++#include <linux/init.h>
 | |
| ++#include <linux/of.h>
 | |
| ++#include <linux/mtd/mtd.h>
 | |
| ++#include <linux/slab.h>
 | |
| ++#include <linux/mtd/partitions.h>
 | |
| ++
 | |
| ++#include "ofpart_bcm4908.h"
 | |
| ++
 | |
| ++#define BLPARAMS_FW_OFFSET		"NAND_RFS_OFS"
 | |
| ++
 | |
| ++static long long bcm4908_partitions_fw_offset(void)
 | |
| ++{
 | |
| ++	struct device_node *root;
 | |
| ++	struct property *prop;
 | |
| ++	const char *s;
 | |
| ++
 | |
| ++	root = of_find_node_by_path("/");
 | |
| ++	if (!root)
 | |
| ++		return -ENOENT;
 | |
| ++
 | |
| ++	of_property_for_each_string(root, "brcm_blparms", prop, s) {
 | |
| ++		size_t len = strlen(BLPARAMS_FW_OFFSET);
 | |
| ++		unsigned long offset;
 | |
| ++		int err;
 | |
| ++
 | |
| ++		if (strncmp(s, BLPARAMS_FW_OFFSET, len) || s[len] != '=')
 | |
| ++			continue;
 | |
| ++
 | |
| ++		err = kstrtoul(s + len + 1, 0, &offset);
 | |
| ++		if (err) {
 | |
| ++			pr_err("failed to parse %s\n", s + len + 1);
 | |
| ++			return err;
 | |
| ++		}
 | |
| ++
 | |
| ++		return offset << 10;
 | |
| ++	}
 | |
| ++
 | |
| ++	return -ENOENT;
 | |
| ++}
 | |
| ++
 | |
| ++int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts)
 | |
| ++{
 | |
| ++	long long fw_offset;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	fw_offset = bcm4908_partitions_fw_offset();
 | |
| ++
 | |
| ++	for (i = 0; i < nr_parts; i++) {
 | |
| ++		if (of_device_is_compatible(parts[i].of_node, "brcm,bcm4908-firmware")) {
 | |
| ++			if (fw_offset < 0 || parts[i].offset == fw_offset)
 | |
| ++				parts[i].name = "firmware";
 | |
| ++			else
 | |
| ++				parts[i].name = "backup";
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/parsers/ofpart_bcm4908.h
 | |
| +@@ -0,0 +1,15 @@
 | |
| ++/* SPDX-License-Identifier: GPL-2.0 */
 | |
| ++#ifndef __BCM4908_PARTITIONS_H
 | |
| ++#define __BCM4908_PARTITIONS_H
 | |
| ++
 | |
| ++#ifdef CONFIG_MTD_OF_PARTS_BCM4908
 | |
| ++int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
 | |
| ++#else
 | |
| ++static inline int bcm4908_partitions_post_parse(struct mtd_info *mtd, struct mtd_partition *parts,
 | |
| ++						int nr_parts)
 | |
| ++{
 | |
| ++	return -EOPNOTSUPP;
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| ++#endif
 | |
| +--- a/drivers/mtd/parsers/ofpart.c
 | |
| ++++ /dev/null
 | |
| +@@ -1,239 +0,0 @@
 | |
| +-// SPDX-License-Identifier: GPL-2.0-or-later
 | |
| +-/*
 | |
| +- * Flash partitions described by the OF (or flattened) device tree
 | |
| +- *
 | |
| +- * Copyright © 2006 MontaVista Software Inc.
 | |
| +- * Author: Vitaly Wool <vwool@ru.mvista.com>
 | |
| +- *
 | |
| +- * Revised to handle newer style flash binding by:
 | |
| +- *   Copyright © 2007 David Gibson, IBM Corporation.
 | |
| +- */
 | |
| +-
 | |
| +-#include <linux/module.h>
 | |
| +-#include <linux/init.h>
 | |
| +-#include <linux/of.h>
 | |
| +-#include <linux/mtd/mtd.h>
 | |
| +-#include <linux/slab.h>
 | |
| +-#include <linux/mtd/partitions.h>
 | |
| +-
 | |
| +-static bool node_has_compatible(struct device_node *pp)
 | |
| +-{
 | |
| +-	return of_get_property(pp, "compatible", NULL);
 | |
| +-}
 | |
| +-
 | |
| +-static int parse_fixed_partitions(struct mtd_info *master,
 | |
| +-				  const struct mtd_partition **pparts,
 | |
| +-				  struct mtd_part_parser_data *data)
 | |
| +-{
 | |
| +-	struct mtd_partition *parts;
 | |
| +-	struct device_node *mtd_node;
 | |
| +-	struct device_node *ofpart_node;
 | |
| +-	const char *partname;
 | |
| +-	struct device_node *pp;
 | |
| +-	int nr_parts, i, ret = 0;
 | |
| +-	bool dedicated = true;
 | |
| +-
 | |
| +-
 | |
| +-	/* Pull of_node from the master device node */
 | |
| +-	mtd_node = mtd_get_of_node(master);
 | |
| +-	if (!mtd_node)
 | |
| +-		return 0;
 | |
| +-
 | |
| +-	ofpart_node = of_get_child_by_name(mtd_node, "partitions");
 | |
| +-	if (!ofpart_node) {
 | |
| +-		/*
 | |
| +-		 * We might get here even when ofpart isn't used at all (e.g.,
 | |
| +-		 * when using another parser), so don't be louder than
 | |
| +-		 * KERN_DEBUG
 | |
| +-		 */
 | |
| +-		pr_debug("%s: 'partitions' subnode not found on %pOF. Trying to parse direct subnodes as partitions.\n",
 | |
| +-			 master->name, mtd_node);
 | |
| +-		ofpart_node = mtd_node;
 | |
| +-		dedicated = false;
 | |
| +-	} else if (!of_device_is_compatible(ofpart_node, "fixed-partitions")) {
 | |
| +-		/* The 'partitions' subnode might be used by another parser */
 | |
| +-		return 0;
 | |
| +-	}
 | |
| +-
 | |
| +-	/* First count the subnodes */
 | |
| +-	nr_parts = 0;
 | |
| +-	for_each_child_of_node(ofpart_node,  pp) {
 | |
| +-		if (!dedicated && node_has_compatible(pp))
 | |
| +-			continue;
 | |
| +-
 | |
| +-		nr_parts++;
 | |
| +-	}
 | |
| +-
 | |
| +-	if (nr_parts == 0)
 | |
| +-		return 0;
 | |
| +-
 | |
| +-	parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
 | |
| +-	if (!parts)
 | |
| +-		return -ENOMEM;
 | |
| +-
 | |
| +-	i = 0;
 | |
| +-	for_each_child_of_node(ofpart_node,  pp) {
 | |
| +-		const __be32 *reg;
 | |
| +-		int len;
 | |
| +-		int a_cells, s_cells;
 | |
| +-
 | |
| +-		if (!dedicated && node_has_compatible(pp))
 | |
| +-			continue;
 | |
| +-
 | |
| +-		reg = of_get_property(pp, "reg", &len);
 | |
| +-		if (!reg) {
 | |
| +-			if (dedicated) {
 | |
| +-				pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n",
 | |
| +-					 master->name, pp,
 | |
| +-					 mtd_node);
 | |
| +-				goto ofpart_fail;
 | |
| +-			} else {
 | |
| +-				nr_parts--;
 | |
| +-				continue;
 | |
| +-			}
 | |
| +-		}
 | |
| +-
 | |
| +-		a_cells = of_n_addr_cells(pp);
 | |
| +-		s_cells = of_n_size_cells(pp);
 | |
| +-		if (len / 4 != a_cells + s_cells) {
 | |
| +-			pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n",
 | |
| +-				 master->name, pp,
 | |
| +-				 mtd_node);
 | |
| +-			goto ofpart_fail;
 | |
| +-		}
 | |
| +-
 | |
| +-		parts[i].offset = of_read_number(reg, a_cells);
 | |
| +-		parts[i].size = of_read_number(reg + a_cells, s_cells);
 | |
| +-		parts[i].of_node = pp;
 | |
| +-
 | |
| +-		partname = of_get_property(pp, "label", &len);
 | |
| +-		if (!partname)
 | |
| +-			partname = of_get_property(pp, "name", &len);
 | |
| +-		parts[i].name = partname;
 | |
| +-
 | |
| +-		if (of_get_property(pp, "read-only", &len))
 | |
| +-			parts[i].mask_flags |= MTD_WRITEABLE;
 | |
| +-
 | |
| +-		if (of_get_property(pp, "lock", &len))
 | |
| +-			parts[i].mask_flags |= MTD_POWERUP_LOCK;
 | |
| +-
 | |
| +-		if (of_property_read_bool(pp, "slc-mode"))
 | |
| +-			parts[i].add_flags |= MTD_SLC_ON_MLC_EMULATION;
 | |
| +-
 | |
| +-		i++;
 | |
| +-	}
 | |
| +-
 | |
| +-	if (!nr_parts)
 | |
| +-		goto ofpart_none;
 | |
| +-
 | |
| +-	*pparts = parts;
 | |
| +-	return nr_parts;
 | |
| +-
 | |
| +-ofpart_fail:
 | |
| +-	pr_err("%s: error parsing ofpart partition %pOF (%pOF)\n",
 | |
| +-	       master->name, pp, mtd_node);
 | |
| +-	ret = -EINVAL;
 | |
| +-ofpart_none:
 | |
| +-	of_node_put(pp);
 | |
| +-	kfree(parts);
 | |
| +-	return ret;
 | |
| +-}
 | |
| +-
 | |
| +-static const struct of_device_id parse_ofpart_match_table[] = {
 | |
| +-	{ .compatible = "fixed-partitions" },
 | |
| +-	{},
 | |
| +-};
 | |
| +-MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
 | |
| +-
 | |
| +-static struct mtd_part_parser ofpart_parser = {
 | |
| +-	.parse_fn = parse_fixed_partitions,
 | |
| +-	.name = "fixed-partitions",
 | |
| +-	.of_match_table = parse_ofpart_match_table,
 | |
| +-};
 | |
| +-
 | |
| +-static int parse_ofoldpart_partitions(struct mtd_info *master,
 | |
| +-				      const struct mtd_partition **pparts,
 | |
| +-				      struct mtd_part_parser_data *data)
 | |
| +-{
 | |
| +-	struct mtd_partition *parts;
 | |
| +-	struct device_node *dp;
 | |
| +-	int i, plen, nr_parts;
 | |
| +-	const struct {
 | |
| +-		__be32 offset, len;
 | |
| +-	} *part;
 | |
| +-	const char *names;
 | |
| +-
 | |
| +-	/* Pull of_node from the master device node */
 | |
| +-	dp = mtd_get_of_node(master);
 | |
| +-	if (!dp)
 | |
| +-		return 0;
 | |
| +-
 | |
| +-	part = of_get_property(dp, "partitions", &plen);
 | |
| +-	if (!part)
 | |
| +-		return 0; /* No partitions found */
 | |
| +-
 | |
| +-	pr_warn("Device tree uses obsolete partition map binding: %pOF\n", dp);
 | |
| +-
 | |
| +-	nr_parts = plen / sizeof(part[0]);
 | |
| +-
 | |
| +-	parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
 | |
| +-	if (!parts)
 | |
| +-		return -ENOMEM;
 | |
| +-
 | |
| +-	names = of_get_property(dp, "partition-names", &plen);
 | |
| +-
 | |
| +-	for (i = 0; i < nr_parts; i++) {
 | |
| +-		parts[i].offset = be32_to_cpu(part->offset);
 | |
| +-		parts[i].size   = be32_to_cpu(part->len) & ~1;
 | |
| +-		/* bit 0 set signifies read only partition */
 | |
| +-		if (be32_to_cpu(part->len) & 1)
 | |
| +-			parts[i].mask_flags = MTD_WRITEABLE;
 | |
| +-
 | |
| +-		if (names && (plen > 0)) {
 | |
| +-			int len = strlen(names) + 1;
 | |
| +-
 | |
| +-			parts[i].name = names;
 | |
| +-			plen -= len;
 | |
| +-			names += len;
 | |
| +-		} else {
 | |
| +-			parts[i].name = "unnamed";
 | |
| +-		}
 | |
| +-
 | |
| +-		part++;
 | |
| +-	}
 | |
| +-
 | |
| +-	*pparts = parts;
 | |
| +-	return nr_parts;
 | |
| +-}
 | |
| +-
 | |
| +-static struct mtd_part_parser ofoldpart_parser = {
 | |
| +-	.parse_fn = parse_ofoldpart_partitions,
 | |
| +-	.name = "ofoldpart",
 | |
| +-};
 | |
| +-
 | |
| +-static int __init ofpart_parser_init(void)
 | |
| +-{
 | |
| +-	register_mtd_parser(&ofpart_parser);
 | |
| +-	register_mtd_parser(&ofoldpart_parser);
 | |
| +-	return 0;
 | |
| +-}
 | |
| +-
 | |
| +-static void __exit ofpart_parser_exit(void)
 | |
| +-{
 | |
| +-	deregister_mtd_parser(&ofpart_parser);
 | |
| +-	deregister_mtd_parser(&ofoldpart_parser);
 | |
| +-}
 | |
| +-
 | |
| +-module_init(ofpart_parser_init);
 | |
| +-module_exit(ofpart_parser_exit);
 | |
| +-
 | |
| +-MODULE_LICENSE("GPL");
 | |
| +-MODULE_DESCRIPTION("Parser for MTD partitioning information in device tree");
 | |
| +-MODULE_AUTHOR("Vitaly Wool, David Gibson");
 | |
| +-/*
 | |
| +- * When MTD core cannot find the requested parser, it tries to load the module
 | |
| +- * with the same name. Since we provide the ofoldpart parser, we should have
 | |
| +- * the corresponding alias.
 | |
| +- */
 | |
| +-MODULE_ALIAS("fixed-partitions");
 | |
| +-MODULE_ALIAS("ofoldpart");
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/parsers/ofpart_core.c
 | |
| +@@ -0,0 +1,263 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0-or-later
 | |
| ++/*
 | |
| ++ * Flash partitions described by the OF (or flattened) device tree
 | |
| ++ *
 | |
| ++ * Copyright © 2006 MontaVista Software Inc.
 | |
| ++ * Author: Vitaly Wool <vwool@ru.mvista.com>
 | |
| ++ *
 | |
| ++ * Revised to handle newer style flash binding by:
 | |
| ++ *   Copyright © 2007 David Gibson, IBM Corporation.
 | |
| ++ */
 | |
| ++
 | |
| ++#include <linux/module.h>
 | |
| ++#include <linux/init.h>
 | |
| ++#include <linux/of.h>
 | |
| ++#include <linux/mtd/mtd.h>
 | |
| ++#include <linux/slab.h>
 | |
| ++#include <linux/mtd/partitions.h>
 | |
| ++
 | |
| ++#include "ofpart_bcm4908.h"
 | |
| ++
 | |
| ++struct fixed_partitions_quirks {
 | |
| ++	int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
 | |
| ++};
 | |
| ++
 | |
| ++struct fixed_partitions_quirks bcm4908_partitions_quirks = {
 | |
| ++	.post_parse = bcm4908_partitions_post_parse,
 | |
| ++};
 | |
| ++
 | |
| ++static const struct of_device_id parse_ofpart_match_table[];
 | |
| ++
 | |
| ++static bool node_has_compatible(struct device_node *pp)
 | |
| ++{
 | |
| ++	return of_get_property(pp, "compatible", NULL);
 | |
| ++}
 | |
| ++
 | |
| ++static int parse_fixed_partitions(struct mtd_info *master,
 | |
| ++				  const struct mtd_partition **pparts,
 | |
| ++				  struct mtd_part_parser_data *data)
 | |
| ++{
 | |
| ++	const struct fixed_partitions_quirks *quirks;
 | |
| ++	const struct of_device_id *of_id;
 | |
| ++	struct mtd_partition *parts;
 | |
| ++	struct device_node *mtd_node;
 | |
| ++	struct device_node *ofpart_node;
 | |
| ++	const char *partname;
 | |
| ++	struct device_node *pp;
 | |
| ++	int nr_parts, i, ret = 0;
 | |
| ++	bool dedicated = true;
 | |
| ++
 | |
| ++	/* Pull of_node from the master device node */
 | |
| ++	mtd_node = mtd_get_of_node(master);
 | |
| ++	if (!mtd_node)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	ofpart_node = of_get_child_by_name(mtd_node, "partitions");
 | |
| ++	if (!ofpart_node) {
 | |
| ++		/*
 | |
| ++		 * We might get here even when ofpart isn't used at all (e.g.,
 | |
| ++		 * when using another parser), so don't be louder than
 | |
| ++		 * KERN_DEBUG
 | |
| ++		 */
 | |
| ++		pr_debug("%s: 'partitions' subnode not found on %pOF. Trying to parse direct subnodes as partitions.\n",
 | |
| ++			 master->name, mtd_node);
 | |
| ++		ofpart_node = mtd_node;
 | |
| ++		dedicated = false;
 | |
| ++	}
 | |
| ++
 | |
| ++	of_id = of_match_node(parse_ofpart_match_table, ofpart_node);
 | |
| ++	if (dedicated && !of_id) {
 | |
| ++		/* The 'partitions' subnode might be used by another parser */
 | |
| ++		return 0;
 | |
| ++	}
 | |
| ++
 | |
| ++	quirks = of_id ? of_id->data : NULL;
 | |
| ++
 | |
| ++	/* First count the subnodes */
 | |
| ++	nr_parts = 0;
 | |
| ++	for_each_child_of_node(ofpart_node,  pp) {
 | |
| ++		if (!dedicated && node_has_compatible(pp))
 | |
| ++			continue;
 | |
| ++
 | |
| ++		nr_parts++;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (nr_parts == 0)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
 | |
| ++	if (!parts)
 | |
| ++		return -ENOMEM;
 | |
| ++
 | |
| ++	i = 0;
 | |
| ++	for_each_child_of_node(ofpart_node,  pp) {
 | |
| ++		const __be32 *reg;
 | |
| ++		int len;
 | |
| ++		int a_cells, s_cells;
 | |
| ++
 | |
| ++		if (!dedicated && node_has_compatible(pp))
 | |
| ++			continue;
 | |
| ++
 | |
| ++		reg = of_get_property(pp, "reg", &len);
 | |
| ++		if (!reg) {
 | |
| ++			if (dedicated) {
 | |
| ++				pr_debug("%s: ofpart partition %pOF (%pOF) missing reg property.\n",
 | |
| ++					 master->name, pp,
 | |
| ++					 mtd_node);
 | |
| ++				goto ofpart_fail;
 | |
| ++			} else {
 | |
| ++				nr_parts--;
 | |
| ++				continue;
 | |
| ++			}
 | |
| ++		}
 | |
| ++
 | |
| ++		a_cells = of_n_addr_cells(pp);
 | |
| ++		s_cells = of_n_size_cells(pp);
 | |
| ++		if (len / 4 != a_cells + s_cells) {
 | |
| ++			pr_debug("%s: ofpart partition %pOF (%pOF) error parsing reg property.\n",
 | |
| ++				 master->name, pp,
 | |
| ++				 mtd_node);
 | |
| ++			goto ofpart_fail;
 | |
| ++		}
 | |
| ++
 | |
| ++		parts[i].offset = of_read_number(reg, a_cells);
 | |
| ++		parts[i].size = of_read_number(reg + a_cells, s_cells);
 | |
| ++		parts[i].of_node = pp;
 | |
| ++
 | |
| ++		partname = of_get_property(pp, "label", &len);
 | |
| ++		if (!partname)
 | |
| ++			partname = of_get_property(pp, "name", &len);
 | |
| ++		parts[i].name = partname;
 | |
| ++
 | |
| ++		if (of_get_property(pp, "read-only", &len))
 | |
| ++			parts[i].mask_flags |= MTD_WRITEABLE;
 | |
| ++
 | |
| ++		if (of_get_property(pp, "lock", &len))
 | |
| ++			parts[i].mask_flags |= MTD_POWERUP_LOCK;
 | |
| ++
 | |
| ++		if (of_property_read_bool(pp, "slc-mode"))
 | |
| ++			parts[i].add_flags |= MTD_SLC_ON_MLC_EMULATION;
 | |
| ++
 | |
| ++		i++;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (!nr_parts)
 | |
| ++		goto ofpart_none;
 | |
| ++
 | |
| ++	if (quirks && quirks->post_parse)
 | |
| ++		quirks->post_parse(master, parts, nr_parts);
 | |
| ++
 | |
| ++	*pparts = parts;
 | |
| ++	return nr_parts;
 | |
| ++
 | |
| ++ofpart_fail:
 | |
| ++	pr_err("%s: error parsing ofpart partition %pOF (%pOF)\n",
 | |
| ++	       master->name, pp, mtd_node);
 | |
| ++	ret = -EINVAL;
 | |
| ++ofpart_none:
 | |
| ++	of_node_put(pp);
 | |
| ++	kfree(parts);
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static const struct of_device_id parse_ofpart_match_table[] = {
 | |
| ++	/* Generic */
 | |
| ++	{ .compatible = "fixed-partitions" },
 | |
| ++	/* Customized */
 | |
| ++	{ .compatible = "brcm,bcm4908-partitions", .data = &bcm4908_partitions_quirks, },
 | |
| ++	{},
 | |
| ++};
 | |
| ++MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
 | |
| ++
 | |
| ++static struct mtd_part_parser ofpart_parser = {
 | |
| ++	.parse_fn = parse_fixed_partitions,
 | |
| ++	.name = "fixed-partitions",
 | |
| ++	.of_match_table = parse_ofpart_match_table,
 | |
| ++};
 | |
| ++
 | |
| ++static int parse_ofoldpart_partitions(struct mtd_info *master,
 | |
| ++				      const struct mtd_partition **pparts,
 | |
| ++				      struct mtd_part_parser_data *data)
 | |
| ++{
 | |
| ++	struct mtd_partition *parts;
 | |
| ++	struct device_node *dp;
 | |
| ++	int i, plen, nr_parts;
 | |
| ++	const struct {
 | |
| ++		__be32 offset, len;
 | |
| ++	} *part;
 | |
| ++	const char *names;
 | |
| ++
 | |
| ++	/* Pull of_node from the master device node */
 | |
| ++	dp = mtd_get_of_node(master);
 | |
| ++	if (!dp)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	part = of_get_property(dp, "partitions", &plen);
 | |
| ++	if (!part)
 | |
| ++		return 0; /* No partitions found */
 | |
| ++
 | |
| ++	pr_warn("Device tree uses obsolete partition map binding: %pOF\n", dp);
 | |
| ++
 | |
| ++	nr_parts = plen / sizeof(part[0]);
 | |
| ++
 | |
| ++	parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
 | |
| ++	if (!parts)
 | |
| ++		return -ENOMEM;
 | |
| ++
 | |
| ++	names = of_get_property(dp, "partition-names", &plen);
 | |
| ++
 | |
| ++	for (i = 0; i < nr_parts; i++) {
 | |
| ++		parts[i].offset = be32_to_cpu(part->offset);
 | |
| ++		parts[i].size   = be32_to_cpu(part->len) & ~1;
 | |
| ++		/* bit 0 set signifies read only partition */
 | |
| ++		if (be32_to_cpu(part->len) & 1)
 | |
| ++			parts[i].mask_flags = MTD_WRITEABLE;
 | |
| ++
 | |
| ++		if (names && (plen > 0)) {
 | |
| ++			int len = strlen(names) + 1;
 | |
| ++
 | |
| ++			parts[i].name = names;
 | |
| ++			plen -= len;
 | |
| ++			names += len;
 | |
| ++		} else {
 | |
| ++			parts[i].name = "unnamed";
 | |
| ++		}
 | |
| ++
 | |
| ++		part++;
 | |
| ++	}
 | |
| ++
 | |
| ++	*pparts = parts;
 | |
| ++	return nr_parts;
 | |
| ++}
 | |
| ++
 | |
| ++static struct mtd_part_parser ofoldpart_parser = {
 | |
| ++	.parse_fn = parse_ofoldpart_partitions,
 | |
| ++	.name = "ofoldpart",
 | |
| ++};
 | |
| ++
 | |
| ++static int __init ofpart_parser_init(void)
 | |
| ++{
 | |
| ++	register_mtd_parser(&ofpart_parser);
 | |
| ++	register_mtd_parser(&ofoldpart_parser);
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void __exit ofpart_parser_exit(void)
 | |
| ++{
 | |
| ++	deregister_mtd_parser(&ofpart_parser);
 | |
| ++	deregister_mtd_parser(&ofoldpart_parser);
 | |
| ++}
 | |
| ++
 | |
| ++module_init(ofpart_parser_init);
 | |
| ++module_exit(ofpart_parser_exit);
 | |
| ++
 | |
| ++MODULE_LICENSE("GPL");
 | |
| ++MODULE_DESCRIPTION("Parser for MTD partitioning information in device tree");
 | |
| ++MODULE_AUTHOR("Vitaly Wool, David Gibson");
 | |
| ++/*
 | |
| ++ * When MTD core cannot find the requested parser, it tries to load the module
 | |
| ++ * with the same name. Since we provide the ofoldpart parser, we should have
 | |
| ++ * the corresponding alias.
 | |
| ++ */
 | |
| ++MODULE_ALIAS("fixed-partitions");
 | |
| ++MODULE_ALIAS("ofoldpart");
 | |
| diff --git a/target/linux/generic/backport-5.10/404-v5.13-mtd-parsers-ofpart-limit-parsing-of-deprecated-DT-sy.patch b/target/linux/generic/backport-5.10/404-v5.13-mtd-parsers-ofpart-limit-parsing-of-deprecated-DT-sy.patch
 | |
| new file mode 100644
 | |
| index 0000000000..55a91d7680
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/404-v5.13-mtd-parsers-ofpart-limit-parsing-of-deprecated-DT-sy.patch
 | |
| @@ -0,0 +1,69 @@
 | |
| +From 2d751203aacf86a1b301a188d8551c7da91043ab Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Tue, 2 Mar 2021 20:00:12 +0100
 | |
| +Subject: [PATCH] mtd: parsers: ofpart: limit parsing of deprecated DT syntax
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +For backward compatibility ofpart still supports the old syntax like:
 | |
| +spi-flash@0 {
 | |
| +	compatible = "jedec,spi-nor";
 | |
| +	reg = <0x0>;
 | |
| +
 | |
| +	partition@0 {
 | |
| +		label = "bootloader";
 | |
| +		reg = <0x0 0x100000>;
 | |
| +	};
 | |
| +};
 | |
| +(without "partitions" subnode).
 | |
| +
 | |
| +There is no reason however to support nested partitions without a clear
 | |
| +"compatible" string like:
 | |
| +partitions {
 | |
| +	compatible = "fixed-partitions";
 | |
| +	#address-cells = <1>;
 | |
| +	#size-cells = <1>;
 | |
| +
 | |
| +	partition@0 {
 | |
| +		label = "bootloader";
 | |
| +		reg = <0x0 0x100000>;
 | |
| +
 | |
| +		partition@0 {
 | |
| +			label = "config";
 | |
| +			reg = <0x80000 0x80000>;
 | |
| +		};
 | |
| +	};
 | |
| +};
 | |
| +(we never officially supported or documented that).
 | |
| +
 | |
| +Make sure ofpart doesn't attempt to parse above.
 | |
| +
 | |
| +Cc: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
 | |
| +Link: https://lore.kernel.org/linux-mtd/20210302190012.1255-1-zajec5@gmail.com
 | |
| +---
 | |
| + drivers/mtd/parsers/ofpart_core.c | 4 +++-
 | |
| + 1 file changed, 3 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/ofpart_core.c
 | |
| ++++ b/drivers/mtd/parsers/ofpart_core.c
 | |
| +@@ -53,7 +53,7 @@ static int parse_fixed_partitions(struct
 | |
| + 		return 0;
 | |
| + 
 | |
| + 	ofpart_node = of_get_child_by_name(mtd_node, "partitions");
 | |
| +-	if (!ofpart_node) {
 | |
| ++	if (!ofpart_node && !master->parent) {
 | |
| + 		/*
 | |
| + 		 * We might get here even when ofpart isn't used at all (e.g.,
 | |
| + 		 * when using another parser), so don't be louder than
 | |
| +@@ -64,6 +64,8 @@ static int parse_fixed_partitions(struct
 | |
| + 		ofpart_node = mtd_node;
 | |
| + 		dedicated = false;
 | |
| + 	}
 | |
| ++	if (!ofpart_node)
 | |
| ++		return 0;
 | |
| + 
 | |
| + 	of_id = of_match_node(parse_ofpart_match_table, ofpart_node);
 | |
| + 	if (dedicated && !of_id) {
 | |
| diff --git a/target/linux/generic/backport-5.10/405-v5.13-mtd-parsers-ofpart-make-symbol-bcm4908_partitions_qu.patch b/target/linux/generic/backport-5.10/405-v5.13-mtd-parsers-ofpart-make-symbol-bcm4908_partitions_qu.patch
 | |
| new file mode 100644
 | |
| index 0000000000..f1b778a6e1
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/405-v5.13-mtd-parsers-ofpart-make-symbol-bcm4908_partitions_qu.patch
 | |
| @@ -0,0 +1,34 @@
 | |
| +From b87b6d2d6f540e29c3f98e1572d64e560d73d6c1 Mon Sep 17 00:00:00 2001
 | |
| +From: Wei Yongjun <weiyongjun1@huawei.com>
 | |
| +Date: Thu, 4 Mar 2021 06:46:00 +0000
 | |
| +Subject: [PATCH] mtd: parsers: ofpart: make symbol 'bcm4908_partitions_quirks'
 | |
| + static
 | |
| +
 | |
| +The sparse tool complains as follows:
 | |
| +
 | |
| +drivers/mtd/parsers/ofpart_core.c:25:32: warning:
 | |
| + symbol 'bcm4908_partitions_quirks' was not declared. Should it be static?
 | |
| +
 | |
| +This symbol is not used outside of ofpart_core.c, so this
 | |
| +commit marks it static.
 | |
| +
 | |
| +Fixes: 457da931b608 ("mtd: parsers: ofpart: support BCM4908 fixed partitions")
 | |
| +Reported-by: Hulk Robot <hulkci@huawei.com>
 | |
| +Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
 | |
| +Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
 | |
| +Link: https://lore.kernel.org/linux-mtd/20210304064600.3279138-1-weiyongjun1@huawei.com
 | |
| +---
 | |
| + drivers/mtd/parsers/ofpart_core.c | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/ofpart_core.c
 | |
| ++++ b/drivers/mtd/parsers/ofpart_core.c
 | |
| +@@ -22,7 +22,7 @@ struct fixed_partitions_quirks {
 | |
| + 	int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
 | |
| + };
 | |
| + 
 | |
| +-struct fixed_partitions_quirks bcm4908_partitions_quirks = {
 | |
| ++static struct fixed_partitions_quirks bcm4908_partitions_quirks = {
 | |
| + 	.post_parse = bcm4908_partitions_post_parse,
 | |
| + };
 | |
| + 
 | |
| diff --git a/target/linux/generic/backport-5.10/406-v5.13-0001-mtd-core-add-nvmem-cells-compatible-to-parse-mtd-as-.patch b/target/linux/generic/backport-5.10/406-v5.13-0001-mtd-core-add-nvmem-cells-compatible-to-parse-mtd-as-.patch
 | |
| new file mode 100644
 | |
| index 0000000000..28335cb71f
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/406-v5.13-0001-mtd-core-add-nvmem-cells-compatible-to-parse-mtd-as-.patch
 | |
| @@ -0,0 +1,38 @@
 | |
| +From a5d83d6e2bc747b13f347962d4b335d70b23559b Mon Sep 17 00:00:00 2001
 | |
| +From: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| +Date: Fri, 12 Mar 2021 07:28:19 +0100
 | |
| +Subject: [PATCH] mtd: core: add nvmem-cells compatible to parse mtd as nvmem
 | |
| + cells
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +Partitions that contains the nvmem-cells compatible will register
 | |
| +their direct subonodes as nvmem cells and the node will be treated as a
 | |
| +nvmem provider.
 | |
| +
 | |
| +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| +Tested-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +---
 | |
| + drivers/mtd/mtdcore.c | 3 ++-
 | |
| + 1 file changed, 2 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/drivers/mtd/mtdcore.c
 | |
| ++++ b/drivers/mtd/mtdcore.c
 | |
| +@@ -531,6 +531,7 @@ static int mtd_nvmem_reg_read(void *priv
 | |
| + 
 | |
| + static int mtd_nvmem_add(struct mtd_info *mtd)
 | |
| + {
 | |
| ++	struct device_node *node = mtd_get_of_node(mtd);
 | |
| + 	struct nvmem_config config = {};
 | |
| + 
 | |
| + 	config.id = -1;
 | |
| +@@ -543,7 +544,7 @@ static int mtd_nvmem_add(struct mtd_info
 | |
| + 	config.stride = 1;
 | |
| + 	config.read_only = true;
 | |
| + 	config.root_only = true;
 | |
| +-	config.no_of_node = true;
 | |
| ++	config.no_of_node = !of_device_is_compatible(node, "nvmem-cells");
 | |
| + 	config.priv = mtd;
 | |
| + 
 | |
| + 	mtd->nvmem = nvmem_register(&config);
 | |
| diff --git a/target/linux/generic/backport-5.10/406-v5.13-0002-dt-bindings-nvmem-drop-nodename-restriction.patch b/target/linux/generic/backport-5.10/406-v5.13-0002-dt-bindings-nvmem-drop-nodename-restriction.patch
 | |
| new file mode 100644
 | |
| index 0000000000..14ea3f6b8c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/406-v5.13-0002-dt-bindings-nvmem-drop-nodename-restriction.patch
 | |
| @@ -0,0 +1,25 @@
 | |
| +From 42645976c3289b03a12f1bd2bc131fd98fc27170 Mon Sep 17 00:00:00 2001
 | |
| +From: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| +Date: Fri, 12 Mar 2021 07:28:20 +0100
 | |
| +Subject: [PATCH] devicetree: nvmem: nvmem: drop $nodename restriction
 | |
| +
 | |
| +Drop $nodename restriction as now mtd partition can also be used as
 | |
| +nvmem provider.
 | |
| +
 | |
| +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| +---
 | |
| + Documentation/devicetree/bindings/nvmem/nvmem.yaml | 3 ---
 | |
| + 1 file changed, 3 deletions(-)
 | |
| +
 | |
| +--- a/Documentation/devicetree/bindings/nvmem/nvmem.yaml
 | |
| ++++ b/Documentation/devicetree/bindings/nvmem/nvmem.yaml
 | |
| +@@ -20,9 +20,6 @@ description: |
 | |
| +   storage device.
 | |
| + 
 | |
| + properties:
 | |
| +-  $nodename:
 | |
| +-    pattern: "^(eeprom|efuse|nvram)(@.*|-[0-9a-f])*$"
 | |
| +-
 | |
| +   "#address-cells":
 | |
| +     const: 1
 | |
| + 
 | |
| diff --git a/target/linux/generic/backport-5.10/406-v5.13-0003-dt-bindings-mtd-Document-use-of-nvmem-cells-compatib.patch b/target/linux/generic/backport-5.10/406-v5.13-0003-dt-bindings-mtd-Document-use-of-nvmem-cells-compatib.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0eb4c637cf
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/406-v5.13-0003-dt-bindings-mtd-Document-use-of-nvmem-cells-compatib.patch
 | |
| @@ -0,0 +1,117 @@
 | |
| +From 377aa0135dc8489312edd3184d143ce3a89ff7ee Mon Sep 17 00:00:00 2001
 | |
| +From: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| +Date: Fri, 12 Mar 2021 07:28:21 +0100
 | |
| +Subject: [PATCH] dt-bindings: mtd: Document use of nvmem-cells compatible
 | |
| +
 | |
| +Document nvmem-cells compatible used to treat mtd partitions as a
 | |
| +nvmem provider.
 | |
| +
 | |
| +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
 | |
| +Reviewed-by: Rob Herring <robh@kernel.org>
 | |
| +---
 | |
| + .../bindings/mtd/partitions/nvmem-cells.yaml  | 99 +++++++++++++++++++
 | |
| + 1 file changed, 99 insertions(+)
 | |
| + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml
 | |
| +
 | |
| +--- /dev/null
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/partitions/nvmem-cells.yaml
 | |
| +@@ -0,0 +1,99 @@
 | |
| ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | |
| ++%YAML 1.2
 | |
| ++---
 | |
| ++$id: http://devicetree.org/schemas/mtd/partitions/nvmem-cells.yaml#
 | |
| ++$schema: http://devicetree.org/meta-schemas/core.yaml#
 | |
| ++
 | |
| ++title: Nvmem cells
 | |
| ++
 | |
| ++description: |
 | |
| ++  Any partition containing the compatible "nvmem-cells" will register as a
 | |
| ++  nvmem provider.
 | |
| ++  Each direct subnodes represents a nvmem cell following the nvmem binding.
 | |
| ++  Nvmem binding to declare nvmem-cells can be found in:
 | |
| ++  Documentation/devicetree/bindings/nvmem/nvmem.yaml
 | |
| ++
 | |
| ++maintainers:
 | |
| ++  - Ansuel Smith <ansuelsmth@gmail.com>
 | |
| ++
 | |
| ++allOf:
 | |
| ++  - $ref: /schemas/nvmem/nvmem.yaml#
 | |
| ++
 | |
| ++properties:
 | |
| ++  compatible:
 | |
| ++    const: nvmem-cells
 | |
| ++
 | |
| ++required:
 | |
| ++  - compatible
 | |
| ++
 | |
| ++additionalProperties: true
 | |
| ++
 | |
| ++examples:
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++      compatible = "fixed-partitions";
 | |
| ++      #address-cells = <1>;
 | |
| ++      #size-cells = <1>;
 | |
| ++
 | |
| ++      /* ... */
 | |
| ++
 | |
| ++      };
 | |
| ++      art: art@1200000 {
 | |
| ++        compatible = "nvmem-cells";
 | |
| ++        reg = <0x1200000 0x0140000>;
 | |
| ++        label = "art";
 | |
| ++        read-only;
 | |
| ++        #address-cells = <1>;
 | |
| ++        #size-cells = <1>;
 | |
| ++
 | |
| ++        macaddr_gmac1: macaddr_gmac1@0 {
 | |
| ++          reg = <0x0 0x6>;
 | |
| ++        };
 | |
| ++
 | |
| ++        macaddr_gmac2: macaddr_gmac2@6 {
 | |
| ++          reg = <0x6 0x6>;
 | |
| ++        };
 | |
| ++
 | |
| ++        pre_cal_24g: pre_cal_24g@1000 {
 | |
| ++          reg = <0x1000 0x2f20>;
 | |
| ++        };
 | |
| ++
 | |
| ++        pre_cal_5g: pre_cal_5g@5000{
 | |
| ++          reg = <0x5000 0x2f20>;
 | |
| ++        };
 | |
| ++      };
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++        compatible = "fixed-partitions";
 | |
| ++        #address-cells = <1>;
 | |
| ++        #size-cells = <1>;
 | |
| ++
 | |
| ++        partition@0 {
 | |
| ++            label = "bootloader";
 | |
| ++            reg = <0x000000 0x100000>;
 | |
| ++            read-only;
 | |
| ++        };
 | |
| ++
 | |
| ++        firmware@100000 {
 | |
| ++            compatible = "brcm,trx";
 | |
| ++            label = "firmware";
 | |
| ++            reg = <0x100000 0xe00000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        calibration@f00000 {
 | |
| ++            compatible = "nvmem-cells";
 | |
| ++            label = "calibration";
 | |
| ++            reg = <0xf00000 0x100000>;
 | |
| ++            ranges = <0 0xf00000 0x100000>;
 | |
| ++            #address-cells = <1>;
 | |
| ++            #size-cells = <1>;
 | |
| ++
 | |
| ++            wifi0@0 {
 | |
| ++                reg = <0x000000 0x080000>;
 | |
| ++            };
 | |
| ++
 | |
| ++            wifi1@80000 {
 | |
| ++                reg = <0x080000 0x080000>;
 | |
| ++            };
 | |
| ++        };
 | |
| ++    };
 | |
| diff --git a/target/linux/generic/backport-5.10/407-v5.13-0001-dt-bindings-mtd-add-binding-for-Linksys-Northstar-pa.patch b/target/linux/generic/backport-5.10/407-v5.13-0001-dt-bindings-mtd-add-binding-for-Linksys-Northstar-pa.patch
 | |
| new file mode 100644
 | |
| index 0000000000..35a4afd67b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/407-v5.13-0001-dt-bindings-mtd-add-binding-for-Linksys-Northstar-pa.patch
 | |
| @@ -0,0 +1,98 @@
 | |
| +From 2fa7294175c76e1ec568aa75c1891fd908728c8d Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Fri, 12 Mar 2021 14:49:18 +0100
 | |
| +Subject: [PATCH] dt-bindings: mtd: add binding for Linksys Northstar
 | |
| + partitions
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +Linksys on Broadcom Northstar devices uses fixed flash layout with
 | |
| +multiple firmware partitions.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Reviewed-by: Rob Herring <robh@kernel.org>
 | |
| +Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
 | |
| +Link: https://lore.kernel.org/linux-mtd/20210312134919.7767-1-zajec5@gmail.com
 | |
| +---
 | |
| + .../mtd/partitions/linksys,ns-partitions.yaml | 74 +++++++++++++++++++
 | |
| + 1 file changed, 74 insertions(+)
 | |
| + create mode 100644 Documentation/devicetree/bindings/mtd/partitions/linksys,ns-partitions.yaml
 | |
| +
 | |
| +--- /dev/null
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/partitions/linksys,ns-partitions.yaml
 | |
| +@@ -0,0 +1,74 @@
 | |
| ++# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
 | |
| ++%YAML 1.2
 | |
| ++---
 | |
| ++$id: http://devicetree.org/schemas/mtd/partitions/linksys,ns-partitions.yaml#
 | |
| ++$schema: http://devicetree.org/meta-schemas/core.yaml#
 | |
| ++
 | |
| ++title: Linksys Northstar partitioning
 | |
| ++
 | |
| ++description: |
 | |
| ++  Linksys devices based on Broadcom Northstar architecture often use two
 | |
| ++  firmware partitions. One is used for regular booting, the other is treated as
 | |
| ++  fallback.
 | |
| ++
 | |
| ++  This binding allows defining all fixed partitions and marking those containing
 | |
| ++  firmware. System can use that information e.g. for booting or flashing
 | |
| ++  purposes.
 | |
| ++
 | |
| ++maintainers:
 | |
| ++  - Rafał Miłecki <rafal@milecki.pl>
 | |
| ++
 | |
| ++properties:
 | |
| ++  compatible:
 | |
| ++    const: linksys,ns-partitions
 | |
| ++
 | |
| ++  "#address-cells":
 | |
| ++    enum: [ 1, 2 ]
 | |
| ++
 | |
| ++  "#size-cells":
 | |
| ++    enum: [ 1, 2 ]
 | |
| ++
 | |
| ++patternProperties:
 | |
| ++  "^partition@[0-9a-f]+$":
 | |
| ++    $ref: "partition.yaml#"
 | |
| ++    properties:
 | |
| ++      compatible:
 | |
| ++        items:
 | |
| ++          - const: linksys,ns-firmware
 | |
| ++          - const: brcm,trx
 | |
| ++    unevaluatedProperties: false
 | |
| ++
 | |
| ++required:
 | |
| ++  - "#address-cells"
 | |
| ++  - "#size-cells"
 | |
| ++
 | |
| ++additionalProperties: false
 | |
| ++
 | |
| ++examples:
 | |
| ++  - |
 | |
| ++    partitions {
 | |
| ++        compatible = "linksys,ns-partitions";
 | |
| ++        #address-cells = <1>;
 | |
| ++        #size-cells = <1>;
 | |
| ++
 | |
| ++        partition@0 {
 | |
| ++            label = "boot";
 | |
| ++            reg = <0x0 0x100000>;
 | |
| ++            read-only;
 | |
| ++        };
 | |
| ++
 | |
| ++        partition@100000 {
 | |
| ++            label = "nvram";
 | |
| ++            reg = <0x100000 0x100000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        partition@200000 {
 | |
| ++            compatible = "linksys,ns-firmware", "brcm,trx";
 | |
| ++            reg = <0x200000 0xf00000>;
 | |
| ++        };
 | |
| ++
 | |
| ++        partition@1100000 {
 | |
| ++            compatible = "linksys,ns-firmware", "brcm,trx";
 | |
| ++            reg = <0x1100000 0xf00000>;
 | |
| ++        };
 | |
| ++    };
 | |
| diff --git a/target/linux/generic/backport-5.10/407-v5.13-0002-mtd-parsers-ofpart-support-Linksys-Northstar-partiti.patch b/target/linux/generic/backport-5.10/407-v5.13-0002-mtd-parsers-ofpart-support-Linksys-Northstar-partiti.patch
 | |
| new file mode 100644
 | |
| index 0000000000..f317889785
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/407-v5.13-0002-mtd-parsers-ofpart-support-Linksys-Northstar-partiti.patch
 | |
| @@ -0,0 +1,156 @@
 | |
| +From 7134a2d026d942210b4d26d6059c9d979ca7866e Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Fri, 12 Mar 2021 14:49:19 +0100
 | |
| +Subject: [PATCH] mtd: parsers: ofpart: support Linksys Northstar partitions
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This allows extending ofpart parser with support for Linksys Northstar
 | |
| +devices. That support uses recently added quirks mechanism.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
 | |
| +Link: https://lore.kernel.org/linux-mtd/20210312134919.7767-2-zajec5@gmail.com
 | |
| +---
 | |
| + drivers/mtd/parsers/Kconfig             | 10 +++++
 | |
| + drivers/mtd/parsers/Makefile            |  1 +
 | |
| + drivers/mtd/parsers/ofpart_core.c       |  6 +++
 | |
| + drivers/mtd/parsers/ofpart_linksys_ns.c | 50 +++++++++++++++++++++++++
 | |
| + drivers/mtd/parsers/ofpart_linksys_ns.h | 18 +++++++++
 | |
| + 5 files changed, 85 insertions(+)
 | |
| + create mode 100644 drivers/mtd/parsers/ofpart_linksys_ns.c
 | |
| + create mode 100644 drivers/mtd/parsers/ofpart_linksys_ns.h
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/Kconfig
 | |
| ++++ b/drivers/mtd/parsers/Kconfig
 | |
| +@@ -76,6 +76,16 @@ config MTD_OF_PARTS_BCM4908
 | |
| + 	  that can have multiple "firmware" partitions. It takes care of
 | |
| + 	  finding currently used one and backup ones.
 | |
| + 
 | |
| ++config MTD_OF_PARTS_LINKSYS_NS
 | |
| ++	bool "Linksys Northstar partitioning support"
 | |
| ++	depends on MTD_OF_PARTS && (ARCH_BCM_5301X || ARCH_BCM4908 || COMPILE_TEST)
 | |
| ++	default ARCH_BCM_5301X
 | |
| ++	help
 | |
| ++	  This provides partitions parser for Linksys devices based on Broadcom
 | |
| ++	  Northstar architecture. Linksys commonly uses fixed flash layout with
 | |
| ++	  two "firmware" partitions. Currently used firmware has to be detected
 | |
| ++	  using CFE environment variable.
 | |
| ++
 | |
| + config MTD_PARSER_IMAGETAG
 | |
| + 	tristate "Parser for BCM963XX Image Tag format partitions"
 | |
| + 	depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
 | |
| +--- a/drivers/mtd/parsers/Makefile
 | |
| ++++ b/drivers/mtd/parsers/Makefile
 | |
| +@@ -6,6 +6,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS)		+= cmdl
 | |
| + obj-$(CONFIG_MTD_OF_PARTS)		+= ofpart.o
 | |
| + ofpart-y				+= ofpart_core.o
 | |
| + ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908)	+= ofpart_bcm4908.o
 | |
| ++ofpart-$(CONFIG_MTD_OF_PARTS_LINKSYS_NS)+= ofpart_linksys_ns.o
 | |
| + obj-$(CONFIG_MTD_PARSER_IMAGETAG)	+= parser_imagetag.o
 | |
| + obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o
 | |
| + obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o
 | |
| +--- a/drivers/mtd/parsers/ofpart_core.c
 | |
| ++++ b/drivers/mtd/parsers/ofpart_core.c
 | |
| +@@ -17,6 +17,7 @@
 | |
| + #include <linux/mtd/partitions.h>
 | |
| + 
 | |
| + #include "ofpart_bcm4908.h"
 | |
| ++#include "ofpart_linksys_ns.h"
 | |
| + 
 | |
| + struct fixed_partitions_quirks {
 | |
| + 	int (*post_parse)(struct mtd_info *mtd, struct mtd_partition *parts, int nr_parts);
 | |
| +@@ -26,6 +27,10 @@ static struct fixed_partitions_quirks bc
 | |
| + 	.post_parse = bcm4908_partitions_post_parse,
 | |
| + };
 | |
| + 
 | |
| ++static struct fixed_partitions_quirks linksys_ns_partitions_quirks = {
 | |
| ++	.post_parse = linksys_ns_partitions_post_parse,
 | |
| ++};
 | |
| ++
 | |
| + static const struct of_device_id parse_ofpart_match_table[];
 | |
| + 
 | |
| + static bool node_has_compatible(struct device_node *pp)
 | |
| +@@ -167,6 +172,7 @@ static const struct of_device_id parse_o
 | |
| + 	{ .compatible = "fixed-partitions" },
 | |
| + 	/* Customized */
 | |
| + 	{ .compatible = "brcm,bcm4908-partitions", .data = &bcm4908_partitions_quirks, },
 | |
| ++	{ .compatible = "linksys,ns-partitions", .data = &linksys_ns_partitions_quirks, },
 | |
| + 	{},
 | |
| + };
 | |
| + MODULE_DEVICE_TABLE(of, parse_ofpart_match_table);
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/parsers/ofpart_linksys_ns.c
 | |
| +@@ -0,0 +1,50 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0
 | |
| ++/*
 | |
| ++ * Copyright (C) 2021 Rafał Miłecki <rafal@milecki.pl>
 | |
| ++ */
 | |
| ++
 | |
| ++#include <linux/bcm47xx_nvram.h>
 | |
| ++#include <linux/mtd/mtd.h>
 | |
| ++#include <linux/mtd/partitions.h>
 | |
| ++
 | |
| ++#include "ofpart_linksys_ns.h"
 | |
| ++
 | |
| ++#define NVRAM_BOOT_PART		"bootpartition"
 | |
| ++
 | |
| ++static int ofpart_linksys_ns_bootpartition(void)
 | |
| ++{
 | |
| ++	char buf[4];
 | |
| ++	int bootpartition;
 | |
| ++
 | |
| ++	/* Check CFE environment variable */
 | |
| ++	if (bcm47xx_nvram_getenv(NVRAM_BOOT_PART, buf, sizeof(buf)) > 0) {
 | |
| ++		if (!kstrtoint(buf, 0, &bootpartition))
 | |
| ++			return bootpartition;
 | |
| ++		pr_warn("Failed to parse %s value \"%s\"\n", NVRAM_BOOT_PART,
 | |
| ++			buf);
 | |
| ++	} else {
 | |
| ++		pr_warn("Failed to get NVRAM \"%s\"\n", NVRAM_BOOT_PART);
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int linksys_ns_partitions_post_parse(struct mtd_info *mtd,
 | |
| ++				     struct mtd_partition *parts,
 | |
| ++				     int nr_parts)
 | |
| ++{
 | |
| ++	int bootpartition = ofpart_linksys_ns_bootpartition();
 | |
| ++	int trx_idx = 0;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	for (i = 0; i < nr_parts; i++) {
 | |
| ++		if (of_device_is_compatible(parts[i].of_node, "linksys,ns-firmware")) {
 | |
| ++			if (trx_idx++ == bootpartition)
 | |
| ++				parts[i].name = "firmware";
 | |
| ++			else
 | |
| ++				parts[i].name = "backup";
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/parsers/ofpart_linksys_ns.h
 | |
| +@@ -0,0 +1,18 @@
 | |
| ++/* SPDX-License-Identifier: GPL-2.0 */
 | |
| ++#ifndef __OFPART_LINKSYS_NS_H
 | |
| ++#define __OFPART_LINKSYS_NS_H
 | |
| ++
 | |
| ++#ifdef CONFIG_MTD_OF_PARTS_LINKSYS_NS
 | |
| ++int linksys_ns_partitions_post_parse(struct mtd_info *mtd,
 | |
| ++				     struct mtd_partition *parts,
 | |
| ++				     int nr_parts);
 | |
| ++#else
 | |
| ++static inline int linksys_ns_partitions_post_parse(struct mtd_info *mtd,
 | |
| ++						   struct mtd_partition *parts,
 | |
| ++						   int nr_parts)
 | |
| ++{
 | |
| ++	return -EOPNOTSUPP;
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| ++#endif
 | |
| diff --git a/target/linux/generic/backport-5.10/600-v5.12-net-extract-napi-poll-functionality-to-__napi_poll.patch b/target/linux/generic/backport-5.10/600-v5.12-net-extract-napi-poll-functionality-to-__napi_poll.patch
 | |
| new file mode 100644
 | |
| index 0000000000..366f18d94d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/600-v5.12-net-extract-napi-poll-functionality-to-__napi_poll.patch
 | |
| @@ -0,0 +1,88 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Mon, 8 Feb 2021 11:34:08 -0800
 | |
| +Subject: [PATCH] net: extract napi poll functionality to __napi_poll()
 | |
| +
 | |
| +This commit introduces a new function __napi_poll() which does the main
 | |
| +logic of the existing napi_poll() function, and will be called by other
 | |
| +functions in later commits.
 | |
| +This idea and implementation is done by Felix Fietkau <nbd@nbd.name> and
 | |
| +is proposed as part of the patch to move napi work to work_queue
 | |
| +context.
 | |
| +This commit by itself is a code restructure.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +Signed-off-by: Wei Wang <weiwan@google.com>
 | |
| +Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
 | |
| +Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| +---
 | |
| +
 | |
| +--- a/net/core/dev.c
 | |
| ++++ b/net/core/dev.c
 | |
| +@@ -6752,15 +6752,10 @@ void __netif_napi_del(struct napi_struct
 | |
| + }
 | |
| + EXPORT_SYMBOL(__netif_napi_del);
 | |
| + 
 | |
| +-static int napi_poll(struct napi_struct *n, struct list_head *repoll)
 | |
| ++static int __napi_poll(struct napi_struct *n, bool *repoll)
 | |
| + {
 | |
| +-	void *have;
 | |
| + 	int work, weight;
 | |
| + 
 | |
| +-	list_del_init(&n->poll_list);
 | |
| +-
 | |
| +-	have = netpoll_poll_lock(n);
 | |
| +-
 | |
| + 	weight = n->weight;
 | |
| + 
 | |
| + 	/* This NAPI_STATE_SCHED test is for avoiding a race
 | |
| +@@ -6780,7 +6775,7 @@ static int napi_poll(struct napi_struct
 | |
| + 			    n->poll, work, weight);
 | |
| + 
 | |
| + 	if (likely(work < weight))
 | |
| +-		goto out_unlock;
 | |
| ++		return work;
 | |
| + 
 | |
| + 	/* Drivers must not modify the NAPI state if they
 | |
| + 	 * consume the entire weight.  In such cases this code
 | |
| +@@ -6789,7 +6784,7 @@ static int napi_poll(struct napi_struct
 | |
| + 	 */
 | |
| + 	if (unlikely(napi_disable_pending(n))) {
 | |
| + 		napi_complete(n);
 | |
| +-		goto out_unlock;
 | |
| ++		return work;
 | |
| + 	}
 | |
| + 
 | |
| + 	if (n->gro_bitmask) {
 | |
| +@@ -6807,12 +6802,29 @@ static int napi_poll(struct napi_struct
 | |
| + 	if (unlikely(!list_empty(&n->poll_list))) {
 | |
| + 		pr_warn_once("%s: Budget exhausted after napi rescheduled\n",
 | |
| + 			     n->dev ? n->dev->name : "backlog");
 | |
| +-		goto out_unlock;
 | |
| ++		return work;
 | |
| + 	}
 | |
| + 
 | |
| +-	list_add_tail(&n->poll_list, repoll);
 | |
| ++	*repoll = true;
 | |
| ++
 | |
| ++	return work;
 | |
| ++}
 | |
| ++
 | |
| ++static int napi_poll(struct napi_struct *n, struct list_head *repoll)
 | |
| ++{
 | |
| ++	bool do_repoll = false;
 | |
| ++	void *have;
 | |
| ++	int work;
 | |
| ++
 | |
| ++	list_del_init(&n->poll_list);
 | |
| ++
 | |
| ++	have = netpoll_poll_lock(n);
 | |
| ++
 | |
| ++	work = __napi_poll(n, &do_repoll);
 | |
| ++
 | |
| ++	if (do_repoll)
 | |
| ++		list_add_tail(&n->poll_list, repoll);
 | |
| + 
 | |
| +-out_unlock:
 | |
| + 	netpoll_poll_unlock(have);
 | |
| + 
 | |
| + 	return work;
 | |
| diff --git a/target/linux/generic/backport-5.10/601-v5.12-net-implement-threaded-able-napi-poll-loop-support.patch b/target/linux/generic/backport-5.10/601-v5.12-net-implement-threaded-able-napi-poll-loop-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..32f22b392c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/601-v5.12-net-implement-threaded-able-napi-poll-loop-support.patch
 | |
| @@ -0,0 +1,261 @@
 | |
| +From: Wei Wang <weiwan@google.com>
 | |
| +Date: Mon, 8 Feb 2021 11:34:09 -0800
 | |
| +Subject: [PATCH] net: implement threaded-able napi poll loop support
 | |
| +
 | |
| +This patch allows running each napi poll loop inside its own
 | |
| +kernel thread.
 | |
| +The kthread is created during netif_napi_add() if dev->threaded
 | |
| +is set. And threaded mode is enabled in napi_enable(). We will
 | |
| +provide a way to set dev->threaded and enable threaded mode
 | |
| +without a device up/down in the following patch.
 | |
| +
 | |
| +Once that threaded mode is enabled and the kthread is
 | |
| +started, napi_schedule() will wake-up such thread instead
 | |
| +of scheduling the softirq.
 | |
| +
 | |
| +The threaded poll loop behaves quite likely the net_rx_action,
 | |
| +but it does not have to manipulate local irqs and uses
 | |
| +an explicit scheduling point based on netdev_budget.
 | |
| +
 | |
| +Co-developed-by: Paolo Abeni <pabeni@redhat.com>
 | |
| +Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 | |
| +Co-developed-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
 | |
| +Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
 | |
| +Co-developed-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +Signed-off-by: Wei Wang <weiwan@google.com>
 | |
| +Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
 | |
| +Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -347,6 +347,7 @@ struct napi_struct {
 | |
| + 	struct list_head	dev_list;
 | |
| + 	struct hlist_node	napi_hash_node;
 | |
| + 	unsigned int		napi_id;
 | |
| ++	struct task_struct	*thread;
 | |
| + };
 | |
| + 
 | |
| + enum {
 | |
| +@@ -357,6 +358,7 @@ enum {
 | |
| + 	NAPI_STATE_LISTED,	/* NAPI added to system lists */
 | |
| + 	NAPI_STATE_NO_BUSY_POLL,/* Do not add in napi_hash, no busy polling */
 | |
| + 	NAPI_STATE_IN_BUSY_POLL,/* sk_busy_loop() owns this NAPI */
 | |
| ++	NAPI_STATE_THREADED,		/* The poll is performed inside its own thread*/
 | |
| + };
 | |
| + 
 | |
| + enum {
 | |
| +@@ -367,6 +369,7 @@ enum {
 | |
| + 	NAPIF_STATE_LISTED	 = BIT(NAPI_STATE_LISTED),
 | |
| + 	NAPIF_STATE_NO_BUSY_POLL = BIT(NAPI_STATE_NO_BUSY_POLL),
 | |
| + 	NAPIF_STATE_IN_BUSY_POLL = BIT(NAPI_STATE_IN_BUSY_POLL),
 | |
| ++	NAPIF_STATE_THREADED	 = BIT(NAPI_STATE_THREADED),
 | |
| + };
 | |
| + 
 | |
| + enum gro_result {
 | |
| +@@ -497,20 +500,7 @@ static inline bool napi_complete(struct
 | |
| +  */
 | |
| + void napi_disable(struct napi_struct *n);
 | |
| + 
 | |
| +-/**
 | |
| +- *	napi_enable - enable NAPI scheduling
 | |
| +- *	@n: NAPI context
 | |
| +- *
 | |
| +- * Resume NAPI from being scheduled on this context.
 | |
| +- * Must be paired with napi_disable.
 | |
| +- */
 | |
| +-static inline void napi_enable(struct napi_struct *n)
 | |
| +-{
 | |
| +-	BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
 | |
| +-	smp_mb__before_atomic();
 | |
| +-	clear_bit(NAPI_STATE_SCHED, &n->state);
 | |
| +-	clear_bit(NAPI_STATE_NPSVC, &n->state);
 | |
| +-}
 | |
| ++void napi_enable(struct napi_struct *n);
 | |
| + 
 | |
| + /**
 | |
| +  *	napi_synchronize - wait until NAPI is not running
 | |
| +@@ -1835,6 +1825,8 @@ enum netdev_priv_flags {
 | |
| +  *
 | |
| +  *	@wol_enabled:	Wake-on-LAN is enabled
 | |
| +  *
 | |
| ++ *	@threaded:	napi threaded mode is enabled
 | |
| ++ *
 | |
| +  *	@net_notifier_list:	List of per-net netdev notifier block
 | |
| +  *				that follow this device when it is moved
 | |
| +  *				to another network namespace.
 | |
| +@@ -2152,6 +2144,7 @@ struct net_device {
 | |
| + 	struct lock_class_key	*qdisc_running_key;
 | |
| + 	bool			proto_down;
 | |
| + 	unsigned		wol_enabled:1;
 | |
| ++	unsigned		threaded:1;
 | |
| + 
 | |
| + 	struct list_head	net_notifier_list;
 | |
| + 
 | |
| +--- a/net/core/dev.c
 | |
| ++++ b/net/core/dev.c
 | |
| +@@ -91,6 +91,7 @@
 | |
| + #include <linux/etherdevice.h>
 | |
| + #include <linux/ethtool.h>
 | |
| + #include <linux/skbuff.h>
 | |
| ++#include <linux/kthread.h>
 | |
| + #include <linux/bpf.h>
 | |
| + #include <linux/bpf_trace.h>
 | |
| + #include <net/net_namespace.h>
 | |
| +@@ -1500,6 +1501,27 @@ void netdev_notify_peers(struct net_devi
 | |
| + }
 | |
| + EXPORT_SYMBOL(netdev_notify_peers);
 | |
| + 
 | |
| ++static int napi_threaded_poll(void *data);
 | |
| ++
 | |
| ++static int napi_kthread_create(struct napi_struct *n)
 | |
| ++{
 | |
| ++	int err = 0;
 | |
| ++
 | |
| ++	/* Create and wake up the kthread once to put it in
 | |
| ++	 * TASK_INTERRUPTIBLE mode to avoid the blocked task
 | |
| ++	 * warning and work with loadavg.
 | |
| ++	 */
 | |
| ++	n->thread = kthread_run(napi_threaded_poll, n, "napi/%s-%d",
 | |
| ++				n->dev->name, n->napi_id);
 | |
| ++	if (IS_ERR(n->thread)) {
 | |
| ++		err = PTR_ERR(n->thread);
 | |
| ++		pr_err("kthread_run failed with err %d\n", err);
 | |
| ++		n->thread = NULL;
 | |
| ++	}
 | |
| ++
 | |
| ++	return err;
 | |
| ++}
 | |
| ++
 | |
| + static int __dev_open(struct net_device *dev, struct netlink_ext_ack *extack)
 | |
| + {
 | |
| + 	const struct net_device_ops *ops = dev->netdev_ops;
 | |
| +@@ -4254,6 +4276,21 @@ int gro_normal_batch __read_mostly = 8;
 | |
| + static inline void ____napi_schedule(struct softnet_data *sd,
 | |
| + 				     struct napi_struct *napi)
 | |
| + {
 | |
| ++	struct task_struct *thread;
 | |
| ++
 | |
| ++	if (test_bit(NAPI_STATE_THREADED, &napi->state)) {
 | |
| ++		/* Paired with smp_mb__before_atomic() in
 | |
| ++		 * napi_enable(). Use READ_ONCE() to guarantee
 | |
| ++		 * a complete read on napi->thread. Only call
 | |
| ++		 * wake_up_process() when it's not NULL.
 | |
| ++		 */
 | |
| ++		thread = READ_ONCE(napi->thread);
 | |
| ++		if (thread) {
 | |
| ++			wake_up_process(thread);
 | |
| ++			return;
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| + 	list_add_tail(&napi->poll_list, &sd->poll_list);
 | |
| + 	__raise_softirq_irqoff(NET_RX_SOFTIRQ);
 | |
| + }
 | |
| +@@ -6705,6 +6742,12 @@ void netif_napi_add(struct net_device *d
 | |
| + 	set_bit(NAPI_STATE_NPSVC, &napi->state);
 | |
| + 	list_add_rcu(&napi->dev_list, &dev->napi_list);
 | |
| + 	napi_hash_add(napi);
 | |
| ++	/* Create kthread for this napi if dev->threaded is set.
 | |
| ++	 * Clear dev->threaded if kthread creation failed so that
 | |
| ++	 * threaded mode will not be enabled in napi_enable().
 | |
| ++	 */
 | |
| ++	if (dev->threaded && napi_kthread_create(napi))
 | |
| ++		dev->threaded = 0;
 | |
| + }
 | |
| + EXPORT_SYMBOL(netif_napi_add);
 | |
| + 
 | |
| +@@ -6721,9 +6764,28 @@ void napi_disable(struct napi_struct *n)
 | |
| + 	hrtimer_cancel(&n->timer);
 | |
| + 
 | |
| + 	clear_bit(NAPI_STATE_DISABLE, &n->state);
 | |
| ++	clear_bit(NAPI_STATE_THREADED, &n->state);
 | |
| + }
 | |
| + EXPORT_SYMBOL(napi_disable);
 | |
| + 
 | |
| ++/**
 | |
| ++ *	napi_enable - enable NAPI scheduling
 | |
| ++ *	@n: NAPI context
 | |
| ++ *
 | |
| ++ * Resume NAPI from being scheduled on this context.
 | |
| ++ * Must be paired with napi_disable.
 | |
| ++ */
 | |
| ++void napi_enable(struct napi_struct *n)
 | |
| ++{
 | |
| ++	BUG_ON(!test_bit(NAPI_STATE_SCHED, &n->state));
 | |
| ++	smp_mb__before_atomic();
 | |
| ++	clear_bit(NAPI_STATE_SCHED, &n->state);
 | |
| ++	clear_bit(NAPI_STATE_NPSVC, &n->state);
 | |
| ++	if (n->dev->threaded && n->thread)
 | |
| ++		set_bit(NAPI_STATE_THREADED, &n->state);
 | |
| ++}
 | |
| ++EXPORT_SYMBOL(napi_enable);
 | |
| ++
 | |
| + static void flush_gro_hash(struct napi_struct *napi)
 | |
| + {
 | |
| + 	int i;
 | |
| +@@ -6749,6 +6811,11 @@ void __netif_napi_del(struct napi_struct
 | |
| + 
 | |
| + 	flush_gro_hash(napi);
 | |
| + 	napi->gro_bitmask = 0;
 | |
| ++
 | |
| ++	if (napi->thread) {
 | |
| ++		kthread_stop(napi->thread);
 | |
| ++		napi->thread = NULL;
 | |
| ++	}
 | |
| + }
 | |
| + EXPORT_SYMBOL(__netif_napi_del);
 | |
| + 
 | |
| +@@ -6830,6 +6897,51 @@ static int napi_poll(struct napi_struct
 | |
| + 	return work;
 | |
| + }
 | |
| + 
 | |
| ++static int napi_thread_wait(struct napi_struct *napi)
 | |
| ++{
 | |
| ++	set_current_state(TASK_INTERRUPTIBLE);
 | |
| ++
 | |
| ++	while (!kthread_should_stop() && !napi_disable_pending(napi)) {
 | |
| ++		if (test_bit(NAPI_STATE_SCHED, &napi->state)) {
 | |
| ++			WARN_ON(!list_empty(&napi->poll_list));
 | |
| ++			__set_current_state(TASK_RUNNING);
 | |
| ++			return 0;
 | |
| ++		}
 | |
| ++
 | |
| ++		schedule();
 | |
| ++		set_current_state(TASK_INTERRUPTIBLE);
 | |
| ++	}
 | |
| ++	__set_current_state(TASK_RUNNING);
 | |
| ++	return -1;
 | |
| ++}
 | |
| ++
 | |
| ++static int napi_threaded_poll(void *data)
 | |
| ++{
 | |
| ++	struct napi_struct *napi = data;
 | |
| ++	void *have;
 | |
| ++
 | |
| ++	while (!napi_thread_wait(napi)) {
 | |
| ++		for (;;) {
 | |
| ++			bool repoll = false;
 | |
| ++
 | |
| ++			local_bh_disable();
 | |
| ++
 | |
| ++			have = netpoll_poll_lock(napi);
 | |
| ++			__napi_poll(napi, &repoll);
 | |
| ++			netpoll_poll_unlock(have);
 | |
| ++
 | |
| ++			__kfree_skb_flush();
 | |
| ++			local_bh_enable();
 | |
| ++
 | |
| ++			if (!repoll)
 | |
| ++				break;
 | |
| ++
 | |
| ++			cond_resched();
 | |
| ++		}
 | |
| ++	}
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static __latent_entropy void net_rx_action(struct softirq_action *h)
 | |
| + {
 | |
| + 	struct softnet_data *sd = this_cpu_ptr(&softnet_data);
 | |
| diff --git a/target/linux/generic/backport-5.10/602-v5.12-net-add-sysfs-attribute-to-control-napi-threaded-mod.patch b/target/linux/generic/backport-5.10/602-v5.12-net-add-sysfs-attribute-to-control-napi-threaded-mod.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e72d5eeca4
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/602-v5.12-net-add-sysfs-attribute-to-control-napi-threaded-mod.patch
 | |
| @@ -0,0 +1,177 @@
 | |
| +From: Wei Wang <weiwan@google.com>
 | |
| +Date: Mon, 8 Feb 2021 11:34:10 -0800
 | |
| +Subject: [PATCH] net: add sysfs attribute to control napi threaded mode
 | |
| +
 | |
| +This patch adds a new sysfs attribute to the network device class.
 | |
| +Said attribute provides a per-device control to enable/disable the
 | |
| +threaded mode for all the napi instances of the given network device,
 | |
| +without the need for a device up/down.
 | |
| +User sets it to 1 or 0 to enable or disable threaded mode.
 | |
| +Note: when switching between threaded and the current softirq based mode
 | |
| +for a napi instance, it will not immediately take effect if the napi is
 | |
| +currently being polled. The mode switch will happen for the next time
 | |
| +napi_schedule() is called.
 | |
| +
 | |
| +Co-developed-by: Paolo Abeni <pabeni@redhat.com>
 | |
| +Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 | |
| +Co-developed-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
 | |
| +Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
 | |
| +Co-developed-by: Felix Fietkau <nbd@nbd.name>
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +Signed-off-by: Wei Wang <weiwan@google.com>
 | |
| +Reviewed-by: Alexander Duyck <alexanderduyck@fb.com>
 | |
| +Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| +---
 | |
| +
 | |
| +--- a/Documentation/ABI/testing/sysfs-class-net
 | |
| ++++ b/Documentation/ABI/testing/sysfs-class-net
 | |
| +@@ -337,3 +337,18 @@ Contact:	netdev@vger.kernel.org
 | |
| + Description:
 | |
| + 		32-bit unsigned integer counting the number of times the link has
 | |
| + 		been down
 | |
| ++
 | |
| ++What:		/sys/class/net/<iface>/threaded
 | |
| ++Date:		Jan 2021
 | |
| ++KernelVersion:	5.12
 | |
| ++Contact:	netdev@vger.kernel.org
 | |
| ++Description:
 | |
| ++		Boolean value to control the threaded mode per device. User could
 | |
| ++		set this value to enable/disable threaded mode for all napi
 | |
| ++		belonging to this device, without the need to do device up/down.
 | |
| ++
 | |
| ++		Possible values:
 | |
| ++		== ==================================
 | |
| ++		0  threaded mode disabled for this dev
 | |
| ++		1  threaded mode enabled for this dev
 | |
| ++		== ==================================
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -491,6 +491,8 @@ static inline bool napi_complete(struct
 | |
| + 	return napi_complete_done(n, 0);
 | |
| + }
 | |
| + 
 | |
| ++int dev_set_threaded(struct net_device *dev, bool threaded);
 | |
| ++
 | |
| + /**
 | |
| +  *	napi_disable - prevent NAPI from scheduling
 | |
| +  *	@n: NAPI context
 | |
| +--- a/net/core/dev.c
 | |
| ++++ b/net/core/dev.c
 | |
| +@@ -4280,8 +4280,9 @@ static inline void ____napi_schedule(str
 | |
| + 
 | |
| + 	if (test_bit(NAPI_STATE_THREADED, &napi->state)) {
 | |
| + 		/* Paired with smp_mb__before_atomic() in
 | |
| +-		 * napi_enable(). Use READ_ONCE() to guarantee
 | |
| +-		 * a complete read on napi->thread. Only call
 | |
| ++		 * napi_enable()/dev_set_threaded().
 | |
| ++		 * Use READ_ONCE() to guarantee a complete
 | |
| ++		 * read on napi->thread. Only call
 | |
| + 		 * wake_up_process() when it's not NULL.
 | |
| + 		 */
 | |
| + 		thread = READ_ONCE(napi->thread);
 | |
| +@@ -6715,6 +6716,49 @@ static void init_gro_hash(struct napi_st
 | |
| + 	napi->gro_bitmask = 0;
 | |
| + }
 | |
| + 
 | |
| ++int dev_set_threaded(struct net_device *dev, bool threaded)
 | |
| ++{
 | |
| ++	struct napi_struct *napi;
 | |
| ++	int err = 0;
 | |
| ++
 | |
| ++	if (dev->threaded == threaded)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	if (threaded) {
 | |
| ++		list_for_each_entry(napi, &dev->napi_list, dev_list) {
 | |
| ++			if (!napi->thread) {
 | |
| ++				err = napi_kthread_create(napi);
 | |
| ++				if (err) {
 | |
| ++					threaded = false;
 | |
| ++					break;
 | |
| ++				}
 | |
| ++			}
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	dev->threaded = threaded;
 | |
| ++
 | |
| ++	/* Make sure kthread is created before THREADED bit
 | |
| ++	 * is set.
 | |
| ++	 */
 | |
| ++	smp_mb__before_atomic();
 | |
| ++
 | |
| ++	/* Setting/unsetting threaded mode on a napi might not immediately
 | |
| ++	 * take effect, if the current napi instance is actively being
 | |
| ++	 * polled. In this case, the switch between threaded mode and
 | |
| ++	 * softirq mode will happen in the next round of napi_schedule().
 | |
| ++	 * This should not cause hiccups/stalls to the live traffic.
 | |
| ++	 */
 | |
| ++	list_for_each_entry(napi, &dev->napi_list, dev_list) {
 | |
| ++		if (threaded)
 | |
| ++			set_bit(NAPI_STATE_THREADED, &napi->state);
 | |
| ++		else
 | |
| ++			clear_bit(NAPI_STATE_THREADED, &napi->state);
 | |
| ++	}
 | |
| ++
 | |
| ++	return err;
 | |
| ++}
 | |
| ++
 | |
| + void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
 | |
| + 		    int (*poll)(struct napi_struct *, int), int weight)
 | |
| + {
 | |
| +--- a/net/core/net-sysfs.c
 | |
| ++++ b/net/core/net-sysfs.c
 | |
| +@@ -538,6 +538,45 @@ static ssize_t phys_switch_id_show(struc
 | |
| + }
 | |
| + static DEVICE_ATTR_RO(phys_switch_id);
 | |
| + 
 | |
| ++static ssize_t threaded_show(struct device *dev,
 | |
| ++			     struct device_attribute *attr, char *buf)
 | |
| ++{
 | |
| ++	struct net_device *netdev = to_net_dev(dev);
 | |
| ++	ssize_t ret = -EINVAL;
 | |
| ++
 | |
| ++	if (!rtnl_trylock())
 | |
| ++		return restart_syscall();
 | |
| ++
 | |
| ++	if (dev_isalive(netdev))
 | |
| ++		ret = sprintf(buf, fmt_dec, netdev->threaded);
 | |
| ++
 | |
| ++	rtnl_unlock();
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static int modify_napi_threaded(struct net_device *dev, unsigned long val)
 | |
| ++{
 | |
| ++	int ret;
 | |
| ++
 | |
| ++	if (list_empty(&dev->napi_list))
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	if (val != 0 && val != 1)
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	ret = dev_set_threaded(dev, val);
 | |
| ++
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static ssize_t threaded_store(struct device *dev,
 | |
| ++			      struct device_attribute *attr,
 | |
| ++			      const char *buf, size_t len)
 | |
| ++{
 | |
| ++	return netdev_store(dev, attr, buf, len, modify_napi_threaded);
 | |
| ++}
 | |
| ++static DEVICE_ATTR_RW(threaded);
 | |
| ++
 | |
| + static struct attribute *net_class_attrs[] __ro_after_init = {
 | |
| + 	&dev_attr_netdev_group.attr,
 | |
| + 	&dev_attr_type.attr,
 | |
| +@@ -570,6 +609,7 @@ static struct attribute *net_class_attrs
 | |
| + 	&dev_attr_proto_down.attr,
 | |
| + 	&dev_attr_carrier_up_count.attr,
 | |
| + 	&dev_attr_carrier_down_count.attr,
 | |
| ++	&dev_attr_threaded.attr,
 | |
| + 	NULL,
 | |
| + };
 | |
| + ATTRIBUTE_GROUPS(net_class);
 | |
| diff --git a/target/linux/generic/backport-5.10/603-v5.12-net-fix-race-between-napi-kthread-mode-and-busy-poll.patch b/target/linux/generic/backport-5.10/603-v5.12-net-fix-race-between-napi-kthread-mode-and-busy-poll.patch
 | |
| new file mode 100644
 | |
| index 0000000000..dddc35918e
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/603-v5.12-net-fix-race-between-napi-kthread-mode-and-busy-poll.patch
 | |
| @@ -0,0 +1,93 @@
 | |
| +From: Wei Wang <weiwan@google.com>
 | |
| +Date: Mon, 1 Mar 2021 17:21:13 -0800
 | |
| +Subject: [PATCH] net: fix race between napi kthread mode and busy poll
 | |
| +
 | |
| +Currently, napi_thread_wait() checks for NAPI_STATE_SCHED bit to
 | |
| +determine if the kthread owns this napi and could call napi->poll() on
 | |
| +it. However, if socket busy poll is enabled, it is possible that the
 | |
| +busy poll thread grabs this SCHED bit (after the previous napi->poll()
 | |
| +invokes napi_complete_done() and clears SCHED bit) and tries to poll
 | |
| +on the same napi. napi_disable() could grab the SCHED bit as well.
 | |
| +This patch tries to fix this race by adding a new bit
 | |
| +NAPI_STATE_SCHED_THREADED in napi->state. This bit gets set in
 | |
| +____napi_schedule() if the threaded mode is enabled, and gets cleared
 | |
| +in napi_complete_done(), and we only poll the napi in kthread if this
 | |
| +bit is set. This helps distinguish the ownership of the napi between
 | |
| +kthread and other scenarios and fixes the race issue.
 | |
| +
 | |
| +Fixes: 29863d41bb6e ("net: implement threaded-able napi poll loop support")
 | |
| +Reported-by: Martin Zaharinov <micron10@gmail.com>
 | |
| +Suggested-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +Signed-off-by: Wei Wang <weiwan@google.com>
 | |
| +Cc: Alexander Duyck <alexanderduyck@fb.com>
 | |
| +Cc: Eric Dumazet <edumazet@google.com>
 | |
| +Cc: Paolo Abeni <pabeni@redhat.com>
 | |
| +Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -359,6 +359,7 @@ enum {
 | |
| + 	NAPI_STATE_NO_BUSY_POLL,/* Do not add in napi_hash, no busy polling */
 | |
| + 	NAPI_STATE_IN_BUSY_POLL,/* sk_busy_loop() owns this NAPI */
 | |
| + 	NAPI_STATE_THREADED,		/* The poll is performed inside its own thread*/
 | |
| ++	NAPI_STATE_SCHED_THREADED,	/* Napi is currently scheduled in threaded mode */
 | |
| + };
 | |
| + 
 | |
| + enum {
 | |
| +@@ -370,6 +371,7 @@ enum {
 | |
| + 	NAPIF_STATE_NO_BUSY_POLL = BIT(NAPI_STATE_NO_BUSY_POLL),
 | |
| + 	NAPIF_STATE_IN_BUSY_POLL = BIT(NAPI_STATE_IN_BUSY_POLL),
 | |
| + 	NAPIF_STATE_THREADED	 = BIT(NAPI_STATE_THREADED),
 | |
| ++	NAPIF_STATE_SCHED_THREADED	= BIT(NAPI_STATE_SCHED_THREADED),
 | |
| + };
 | |
| + 
 | |
| + enum gro_result {
 | |
| +--- a/net/core/dev.c
 | |
| ++++ b/net/core/dev.c
 | |
| +@@ -4287,6 +4287,8 @@ static inline void ____napi_schedule(str
 | |
| + 		 */
 | |
| + 		thread = READ_ONCE(napi->thread);
 | |
| + 		if (thread) {
 | |
| ++			if (thread->state != TASK_INTERRUPTIBLE)
 | |
| ++				set_bit(NAPI_STATE_SCHED_THREADED, &napi->state);
 | |
| + 			wake_up_process(thread);
 | |
| + 			return;
 | |
| + 		}
 | |
| +@@ -6507,7 +6509,8 @@ bool napi_complete_done(struct napi_stru
 | |
| + 
 | |
| + 		WARN_ON_ONCE(!(val & NAPIF_STATE_SCHED));
 | |
| + 
 | |
| +-		new = val & ~(NAPIF_STATE_MISSED | NAPIF_STATE_SCHED);
 | |
| ++		new = val & ~(NAPIF_STATE_MISSED | NAPIF_STATE_SCHED |
 | |
| ++			      NAPIF_STATE_SCHED_THREADED);
 | |
| + 
 | |
| + 		/* If STATE_MISSED was set, leave STATE_SCHED set,
 | |
| + 		 * because we will call napi->poll() one more time.
 | |
| +@@ -6943,16 +6946,25 @@ static int napi_poll(struct napi_struct
 | |
| + 
 | |
| + static int napi_thread_wait(struct napi_struct *napi)
 | |
| + {
 | |
| ++	bool woken = false;
 | |
| ++
 | |
| + 	set_current_state(TASK_INTERRUPTIBLE);
 | |
| + 
 | |
| + 	while (!kthread_should_stop() && !napi_disable_pending(napi)) {
 | |
| +-		if (test_bit(NAPI_STATE_SCHED, &napi->state)) {
 | |
| ++		/* Testing SCHED_THREADED bit here to make sure the current
 | |
| ++		 * kthread owns this napi and could poll on this napi.
 | |
| ++		 * Testing SCHED bit is not enough because SCHED bit might be
 | |
| ++		 * set by some other busy poll thread or by napi_disable().
 | |
| ++		 */
 | |
| ++		if (test_bit(NAPI_STATE_SCHED_THREADED, &napi->state) || woken) {
 | |
| + 			WARN_ON(!list_empty(&napi->poll_list));
 | |
| + 			__set_current_state(TASK_RUNNING);
 | |
| + 			return 0;
 | |
| + 		}
 | |
| + 
 | |
| + 		schedule();
 | |
| ++		/* woken being true indicates this thread owns this napi. */
 | |
| ++		woken = true;
 | |
| + 		set_current_state(TASK_INTERRUPTIBLE);
 | |
| + 	}
 | |
| + 	__set_current_state(TASK_RUNNING);
 | |
| diff --git a/target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch b/target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4b83641291
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/604-v5.12-net-fix-hangup-on-napi_disable-for-threaded-napi.patch
 | |
| @@ -0,0 +1,53 @@
 | |
| +From: Paolo Abeni <pabeni@redhat.com>
 | |
| +Date: Fri, 9 Apr 2021 17:24:17 +0200
 | |
| +Subject: [PATCH] net: fix hangup on napi_disable for threaded napi
 | |
| +
 | |
| +napi_disable() is subject to an hangup, when the threaded
 | |
| +mode is enabled and the napi is under heavy traffic.
 | |
| +
 | |
| +If the relevant napi has been scheduled and the napi_disable()
 | |
| +kicks in before the next napi_threaded_wait() completes - so
 | |
| +that the latter quits due to the napi_disable_pending() condition,
 | |
| +the existing code leaves the NAPI_STATE_SCHED bit set and the
 | |
| +napi_disable() loop waiting for such bit will hang.
 | |
| +
 | |
| +This patch addresses the issue by dropping the NAPI_STATE_DISABLE
 | |
| +bit test in napi_thread_wait(). The later napi_threaded_poll()
 | |
| +iteration will take care of clearing the NAPI_STATE_SCHED.
 | |
| +
 | |
| +This also addresses a related problem reported by Jakub:
 | |
| +before this patch a napi_disable()/napi_enable() pair killed
 | |
| +the napi thread, effectively disabling the threaded mode.
 | |
| +On the patched kernel napi_disable() simply stops scheduling
 | |
| +the relevant thread.
 | |
| +
 | |
| +v1 -> v2:
 | |
| +  - let the main napi_thread_poll() loop clear the SCHED bit
 | |
| +
 | |
| +Reported-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +Fixes: 29863d41bb6e ("net: implement threaded-able napi poll loop support")
 | |
| +Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 | |
| +Reviewed-by: Eric Dumazet <edumazet@google.com>
 | |
| +Link: https://lore.kernel.org/r/883923fa22745a9589e8610962b7dc59df09fb1f.1617981844.git.pabeni@redhat.com
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +---
 | |
| +
 | |
| +--- a/net/core/dev.c
 | |
| ++++ b/net/core/dev.c
 | |
| +@@ -6951,7 +6951,7 @@ static int napi_thread_wait(struct napi_
 | |
| + 
 | |
| + 	set_current_state(TASK_INTERRUPTIBLE);
 | |
| + 
 | |
| +-	while (!kthread_should_stop() && !napi_disable_pending(napi)) {
 | |
| ++	while (!kthread_should_stop()) {
 | |
| + 		/* Testing SCHED_THREADED bit here to make sure the current
 | |
| + 		 * kthread owns this napi and could poll on this napi.
 | |
| + 		 * Testing SCHED bit is not enough because SCHED bit might be
 | |
| +@@ -6969,6 +6969,7 @@ static int napi_thread_wait(struct napi_
 | |
| + 		set_current_state(TASK_INTERRUPTIBLE);
 | |
| + 	}
 | |
| + 	__set_current_state(TASK_RUNNING);
 | |
| ++
 | |
| + 	return -1;
 | |
| + }
 | |
| + 
 | |
| diff --git a/target/linux/generic/backport-5.10/770-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch b/target/linux/generic/backport-5.10/770-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch
 | |
| new file mode 100644
 | |
| index 0000000000..c43cb4d1f2
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/770-v5.12-net-bridge-notify-switchdev-of-disappearance-of-old-.patch
 | |
| @@ -0,0 +1,126 @@
 | |
| +From 90dc8fd36078a536671adae884d0b929cce6480a Mon Sep 17 00:00:00 2001
 | |
| +From: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Date: Wed, 6 Jan 2021 11:51:30 +0200
 | |
| +Subject: [PATCH] net: bridge: notify switchdev of disappearance of old FDB
 | |
| + entry upon migration
 | |
| +
 | |
| +Currently the bridge emits atomic switchdev notifications for
 | |
| +dynamically learnt FDB entries. Monitoring these notifications works
 | |
| +wonders for switchdev drivers that want to keep their hardware FDB in
 | |
| +sync with the bridge's FDB.
 | |
| +
 | |
| +For example station A wants to talk to station B in the diagram below,
 | |
| +and we are concerned with the behavior of the bridge on the DUT device:
 | |
| +
 | |
| +                   DUT
 | |
| + +-------------------------------------+
 | |
| + |                 br0                 |
 | |
| + | +------+ +------+ +------+ +------+ |
 | |
| + | |      | |      | |      | |      | |
 | |
| + | | swp0 | | swp1 | | swp2 | | eth0 | |
 | |
| + +-------------------------------------+
 | |
| +      |        |                  |
 | |
| +  Station A    |                  |
 | |
| +               |                  |
 | |
| +         +--+------+--+    +--+------+--+
 | |
| +         |  |      |  |    |  |      |  |
 | |
| +         |  | swp0 |  |    |  | swp0 |  |
 | |
| + Another |  +------+  |    |  +------+  | Another
 | |
| +  switch |     br0    |    |     br0    | switch
 | |
| +         |  +------+  |    |  +------+  |
 | |
| +         |  |      |  |    |  |      |  |
 | |
| +         |  | swp1 |  |    |  | swp1 |  |
 | |
| +         +--+------+--+    +--+------+--+
 | |
| +                                  |
 | |
| +                              Station B
 | |
| +
 | |
| +Interfaces swp0, swp1, swp2 are handled by a switchdev driver that has
 | |
| +the following property: frames injected from its control interface bypass
 | |
| +the internal address analyzer logic, and therefore, this hardware does
 | |
| +not learn from the source address of packets transmitted by the network
 | |
| +stack through it. So, since bridging between eth0 (where Station B is
 | |
| +attached) and swp0 (where Station A is attached) is done in software,
 | |
| +the switchdev hardware will never learn the source address of Station B.
 | |
| +So the traffic towards that destination will be treated as unknown, i.e.
 | |
| +flooded.
 | |
| +
 | |
| +This is where the bridge notifications come in handy. When br0 on the
 | |
| +DUT sees frames with Station B's MAC address on eth0, the switchdev
 | |
| +driver gets these notifications and can install a rule to send frames
 | |
| +towards Station B's address that are incoming from swp0, swp1, swp2,
 | |
| +only towards the control interface. This is all switchdev driver private
 | |
| +business, which the notification makes possible.
 | |
| +
 | |
| +All is fine until someone unplugs Station B's cable and moves it to the
 | |
| +other switch:
 | |
| +
 | |
| +                   DUT
 | |
| + +-------------------------------------+
 | |
| + |                 br0                 |
 | |
| + | +------+ +------+ +------+ +------+ |
 | |
| + | |      | |      | |      | |      | |
 | |
| + | | swp0 | | swp1 | | swp2 | | eth0 | |
 | |
| + +-------------------------------------+
 | |
| +      |        |                  |
 | |
| +  Station A    |                  |
 | |
| +               |                  |
 | |
| +         +--+------+--+    +--+------+--+
 | |
| +         |  |      |  |    |  |      |  |
 | |
| +         |  | swp0 |  |    |  | swp0 |  |
 | |
| + Another |  +------+  |    |  +------+  | Another
 | |
| +  switch |     br0    |    |     br0    | switch
 | |
| +         |  +------+  |    |  +------+  |
 | |
| +         |  |      |  |    |  |      |  |
 | |
| +         |  | swp1 |  |    |  | swp1 |  |
 | |
| +         +--+------+--+    +--+------+--+
 | |
| +               |
 | |
| +           Station B
 | |
| +
 | |
| +Luckily for the use cases we care about, Station B is noisy enough that
 | |
| +the DUT hears it (on swp1 this time). swp1 receives the frames and
 | |
| +delivers them to the bridge, who enters the unlikely path in br_fdb_update
 | |
| +of updating an existing entry. It moves the entry in the software bridge
 | |
| +to swp1 and emits an addition notification towards that.
 | |
| +
 | |
| +As far as the switchdev driver is concerned, all that it needs to ensure
 | |
| +is that traffic between Station A and Station B is not forever broken.
 | |
| +If it does nothing, then the stale rule to send frames for Station B
 | |
| +towards the control interface remains in place. But Station B is no
 | |
| +longer reachable via the control interface, but via a port that can
 | |
| +offload the bridge port learning attribute. It's just that the port is
 | |
| +prevented from learning this address, since the rule overrides FDB
 | |
| +updates. So the rule needs to go. The question is via what mechanism.
 | |
| +
 | |
| +It sure would be possible for this switchdev driver to keep track of all
 | |
| +addresses which are sent to the control interface, and then also listen
 | |
| +for bridge notifier events on its own ports, searching for the ones that
 | |
| +have a MAC address which was previously sent to the control interface.
 | |
| +But this is cumbersome and inefficient. Instead, with one small change,
 | |
| +the bridge could notify of the address deletion from the old port, in a
 | |
| +symmetrical manner with how it did for the insertion. Then the switchdev
 | |
| +driver would not be required to monitor learn/forget events for its own
 | |
| +ports. It could just delete the rule towards the control interface upon
 | |
| +bridge entry migration. This would make hardware address learning be
 | |
| +possible again. Then it would take a few more packets until the hardware
 | |
| +and software FDB would be in sync again.
 | |
| +
 | |
| +Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
 | |
| +Reviewed-by: Ido Schimmel <idosch@nvidia.com>
 | |
| +Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | |
| +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +---
 | |
| + net/bridge/br_fdb.c | 1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/net/bridge/br_fdb.c
 | |
| ++++ b/net/bridge/br_fdb.c
 | |
| +@@ -602,6 +602,7 @@ void br_fdb_update(struct net_bridge *br
 | |
| + 			/* fastpath: update of existing entry */
 | |
| + 			if (unlikely(source != fdb->dst &&
 | |
| + 				     !test_bit(BR_FDB_STICKY, &fdb->flags))) {
 | |
| ++				br_switchdev_fdb_notify(fdb, RTM_DELNEIGH);
 | |
| + 				fdb->dst = source;
 | |
| + 				fdb_modified = true;
 | |
| + 				/* Take over HW learned entry */
 | |
| diff --git a/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch b/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
 | |
| new file mode 100644
 | |
| index 0000000000..ecb81004cb
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/771-v5.12-net-dsa-be-louder-when-a-non-legacy-FDB-operation-fa.patch
 | |
| @@ -0,0 +1,52 @@
 | |
| +From 2fd186501b1cff155cc4a755c210793cfc0dffb5 Mon Sep 17 00:00:00 2001
 | |
| +From: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Date: Wed, 6 Jan 2021 11:51:31 +0200
 | |
| +Subject: [PATCH] net: dsa: be louder when a non-legacy FDB operation fails
 | |
| +
 | |
| +The dev_close() call was added in commit c9eb3e0f8701 ("net: dsa: Add
 | |
| +support for learning FDB through notification") "to indicate inconsistent
 | |
| +situation" when we could not delete an FDB entry from the port.
 | |
| +
 | |
| +bridge fdb del d8:58:d7:00:ca:6d dev swp0 self master
 | |
| +
 | |
| +It is a bit drastic and at the same time not helpful if the above fails
 | |
| +to only print with netdev_dbg log level, but on the other hand to bring
 | |
| +the interface down.
 | |
| +
 | |
| +So increase the verbosity of the error message, and drop dev_close().
 | |
| +
 | |
| +Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | |
| +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +---
 | |
| + net/dsa/slave.c | 10 +++++++---
 | |
| + 1 file changed, 7 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2075,7 +2075,9 @@ static void dsa_slave_switchdev_event_wo
 | |
| + 
 | |
| + 		err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
 | |
| + 		if (err) {
 | |
| +-			netdev_dbg(dev, "fdb add failed err=%d\n", err);
 | |
| ++			netdev_err(dev,
 | |
| ++				   "failed to add %pM vid %d to fdb: %d\n",
 | |
| ++				   fdb_info->addr, fdb_info->vid, err);
 | |
| + 			break;
 | |
| + 		}
 | |
| + 		fdb_info->offloaded = true;
 | |
| +@@ -2090,9 +2092,11 @@ static void dsa_slave_switchdev_event_wo
 | |
| + 
 | |
| + 		err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
 | |
| + 		if (err) {
 | |
| +-			netdev_dbg(dev, "fdb del failed err=%d\n", err);
 | |
| +-			dev_close(dev);
 | |
| ++			netdev_err(dev,
 | |
| ++				   "failed to delete %pM vid %d from fdb: %d\n",
 | |
| ++				   fdb_info->addr, fdb_info->vid, err);
 | |
| + 		}
 | |
| ++
 | |
| + 		break;
 | |
| + 	}
 | |
| + 	rtnl_unlock();
 | |
| diff --git a/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch b/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
 | |
| new file mode 100644
 | |
| index 0000000000..bb943f1312
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/772-v5.12-net-dsa-don-t-use-switchdev_notifier_fdb_info-in-dsa.patch
 | |
| @@ -0,0 +1,226 @@
 | |
| +From c4bb76a9a0ef87c4cc1f636defed5f12deb9f5a7 Mon Sep 17 00:00:00 2001
 | |
| +From: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Date: Wed, 6 Jan 2021 11:51:32 +0200
 | |
| +Subject: [PATCH] net: dsa: don't use switchdev_notifier_fdb_info in
 | |
| + dsa_switchdev_event_work
 | |
| +
 | |
| +Currently DSA doesn't add FDB entries on the CPU port, because it only
 | |
| +does so through switchdev, which is associated with a net_device, and
 | |
| +there are none of those for the CPU port.
 | |
| +
 | |
| +But actually FDB addresses on the CPU port have some use cases of their
 | |
| +own, if the switchdev operations are initiated from within the DSA
 | |
| +layer. There is just one problem with the existing code: it passes a
 | |
| +structure in dsa_switchdev_event_work which was retrieved directly from
 | |
| +switchdev, so it contains a net_device. We need to generalize the
 | |
| +contents to something that covers the CPU port as well: the "ds, port"
 | |
| +tuple is fine for that.
 | |
| +
 | |
| +Note that the new procedure for notifying the successful FDB offload is
 | |
| +inspired from the rocker model.
 | |
| +
 | |
| +Also, nothing was being done if added_by_user was false. Let's check for
 | |
| +that a lot earlier, and don't actually bother to schedule the worker
 | |
| +for nothing.
 | |
| +
 | |
| +Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +---
 | |
| + net/dsa/dsa_priv.h |  12 +++++
 | |
| + net/dsa/slave.c    | 106 ++++++++++++++++++++++-----------------------
 | |
| + 2 files changed, 65 insertions(+), 53 deletions(-)
 | |
| +
 | |
| +--- a/net/dsa/dsa_priv.h
 | |
| ++++ b/net/dsa/dsa_priv.h
 | |
| +@@ -73,6 +73,18 @@ struct dsa_notifier_mtu_info {
 | |
| + 	int mtu;
 | |
| + };
 | |
| + 
 | |
| ++struct dsa_switchdev_event_work {
 | |
| ++	struct dsa_switch *ds;
 | |
| ++	int port;
 | |
| ++	struct work_struct work;
 | |
| ++	unsigned long event;
 | |
| ++	/* Specific for SWITCHDEV_FDB_ADD_TO_DEVICE and
 | |
| ++	 * SWITCHDEV_FDB_DEL_TO_DEVICE
 | |
| ++	 */
 | |
| ++	unsigned char addr[ETH_ALEN];
 | |
| ++	u16 vid;
 | |
| ++};
 | |
| ++
 | |
| + struct dsa_slave_priv {
 | |
| + 	/* Copy of CPU port xmit for faster access in slave transmit hot path */
 | |
| + 	struct sk_buff *	(*xmit)(struct sk_buff *skb,
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2050,76 +2050,66 @@ static int dsa_slave_netdevice_event(str
 | |
| + 	return NOTIFY_DONE;
 | |
| + }
 | |
| + 
 | |
| +-struct dsa_switchdev_event_work {
 | |
| +-	struct work_struct work;
 | |
| +-	struct switchdev_notifier_fdb_info fdb_info;
 | |
| +-	struct net_device *dev;
 | |
| +-	unsigned long event;
 | |
| +-};
 | |
| ++static void
 | |
| ++dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work)
 | |
| ++{
 | |
| ++	struct dsa_switch *ds = switchdev_work->ds;
 | |
| ++	struct switchdev_notifier_fdb_info info;
 | |
| ++	struct dsa_port *dp;
 | |
| ++
 | |
| ++	if (!dsa_is_user_port(ds, switchdev_work->port))
 | |
| ++		return;
 | |
| ++
 | |
| ++	info.addr = switchdev_work->addr;
 | |
| ++	info.vid = switchdev_work->vid;
 | |
| ++	info.offloaded = true;
 | |
| ++	dp = dsa_to_port(ds, switchdev_work->port);
 | |
| ++	call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED,
 | |
| ++				 dp->slave, &info.info, NULL);
 | |
| ++}
 | |
| + 
 | |
| + static void dsa_slave_switchdev_event_work(struct work_struct *work)
 | |
| + {
 | |
| + 	struct dsa_switchdev_event_work *switchdev_work =
 | |
| + 		container_of(work, struct dsa_switchdev_event_work, work);
 | |
| +-	struct net_device *dev = switchdev_work->dev;
 | |
| +-	struct switchdev_notifier_fdb_info *fdb_info;
 | |
| +-	struct dsa_port *dp = dsa_slave_to_port(dev);
 | |
| ++	struct dsa_switch *ds = switchdev_work->ds;
 | |
| ++	struct dsa_port *dp;
 | |
| + 	int err;
 | |
| + 
 | |
| ++	dp = dsa_to_port(ds, switchdev_work->port);
 | |
| ++
 | |
| + 	rtnl_lock();
 | |
| + 	switch (switchdev_work->event) {
 | |
| + 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
 | |
| +-		fdb_info = &switchdev_work->fdb_info;
 | |
| +-		if (!fdb_info->added_by_user)
 | |
| +-			break;
 | |
| +-
 | |
| +-		err = dsa_port_fdb_add(dp, fdb_info->addr, fdb_info->vid);
 | |
| ++		err = dsa_port_fdb_add(dp, switchdev_work->addr,
 | |
| ++				       switchdev_work->vid);
 | |
| + 		if (err) {
 | |
| +-			netdev_err(dev,
 | |
| +-				   "failed to add %pM vid %d to fdb: %d\n",
 | |
| +-				   fdb_info->addr, fdb_info->vid, err);
 | |
| ++			dev_err(ds->dev,
 | |
| ++				"port %d failed to add %pM vid %d to fdb: %d\n",
 | |
| ++				dp->index, switchdev_work->addr,
 | |
| ++				switchdev_work->vid, err);
 | |
| + 			break;
 | |
| + 		}
 | |
| +-		fdb_info->offloaded = true;
 | |
| +-		call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, dev,
 | |
| +-					 &fdb_info->info, NULL);
 | |
| ++		dsa_fdb_offload_notify(switchdev_work);
 | |
| + 		break;
 | |
| + 
 | |
| + 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
 | |
| +-		fdb_info = &switchdev_work->fdb_info;
 | |
| +-		if (!fdb_info->added_by_user)
 | |
| +-			break;
 | |
| +-
 | |
| +-		err = dsa_port_fdb_del(dp, fdb_info->addr, fdb_info->vid);
 | |
| ++		err = dsa_port_fdb_del(dp, switchdev_work->addr,
 | |
| ++				       switchdev_work->vid);
 | |
| + 		if (err) {
 | |
| +-			netdev_err(dev,
 | |
| +-				   "failed to delete %pM vid %d from fdb: %d\n",
 | |
| +-				   fdb_info->addr, fdb_info->vid, err);
 | |
| ++			dev_err(ds->dev,
 | |
| ++				"port %d failed to delete %pM vid %d from fdb: %d\n",
 | |
| ++				dp->index, switchdev_work->addr,
 | |
| ++				switchdev_work->vid, err);
 | |
| + 		}
 | |
| + 
 | |
| + 		break;
 | |
| + 	}
 | |
| + 	rtnl_unlock();
 | |
| + 
 | |
| +-	kfree(switchdev_work->fdb_info.addr);
 | |
| + 	kfree(switchdev_work);
 | |
| +-	dev_put(dev);
 | |
| +-}
 | |
| +-
 | |
| +-static int
 | |
| +-dsa_slave_switchdev_fdb_work_init(struct dsa_switchdev_event_work *
 | |
| +-				  switchdev_work,
 | |
| +-				  const struct switchdev_notifier_fdb_info *
 | |
| +-				  fdb_info)
 | |
| +-{
 | |
| +-	memcpy(&switchdev_work->fdb_info, fdb_info,
 | |
| +-	       sizeof(switchdev_work->fdb_info));
 | |
| +-	switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
 | |
| +-	if (!switchdev_work->fdb_info.addr)
 | |
| +-		return -ENOMEM;
 | |
| +-	ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
 | |
| +-			fdb_info->addr);
 | |
| +-	return 0;
 | |
| ++	if (dsa_is_user_port(ds, dp->index))
 | |
| ++		dev_put(dp->slave);
 | |
| + }
 | |
| + 
 | |
| + /* Called under rcu_read_lock() */
 | |
| +@@ -2127,7 +2117,9 @@ static int dsa_slave_switchdev_event(str
 | |
| + 				     unsigned long event, void *ptr)
 | |
| + {
 | |
| + 	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
 | |
| ++	const struct switchdev_notifier_fdb_info *fdb_info;
 | |
| + 	struct dsa_switchdev_event_work *switchdev_work;
 | |
| ++	struct dsa_port *dp;
 | |
| + 	int err;
 | |
| + 
 | |
| + 	if (event == SWITCHDEV_PORT_ATTR_SET) {
 | |
| +@@ -2140,20 +2132,32 @@ static int dsa_slave_switchdev_event(str
 | |
| + 	if (!dsa_slave_dev_check(dev))
 | |
| + 		return NOTIFY_DONE;
 | |
| + 
 | |
| ++	dp = dsa_slave_to_port(dev);
 | |
| ++
 | |
| + 	switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
 | |
| + 	if (!switchdev_work)
 | |
| + 		return NOTIFY_BAD;
 | |
| + 
 | |
| + 	INIT_WORK(&switchdev_work->work,
 | |
| + 		  dsa_slave_switchdev_event_work);
 | |
| +-	switchdev_work->dev = dev;
 | |
| ++	switchdev_work->ds = dp->ds;
 | |
| ++	switchdev_work->port = dp->index;
 | |
| + 	switchdev_work->event = event;
 | |
| + 
 | |
| + 	switch (event) {
 | |
| + 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
 | |
| + 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
 | |
| +-		if (dsa_slave_switchdev_fdb_work_init(switchdev_work, ptr))
 | |
| +-			goto err_fdb_work_init;
 | |
| ++		fdb_info = ptr;
 | |
| ++
 | |
| ++		if (!fdb_info->added_by_user) {
 | |
| ++			kfree(switchdev_work);
 | |
| ++			return NOTIFY_OK;
 | |
| ++		}
 | |
| ++
 | |
| ++		ether_addr_copy(switchdev_work->addr,
 | |
| ++				fdb_info->addr);
 | |
| ++		switchdev_work->vid = fdb_info->vid;
 | |
| ++
 | |
| + 		dev_hold(dev);
 | |
| + 		break;
 | |
| + 	default:
 | |
| +@@ -2163,10 +2167,6 @@ static int dsa_slave_switchdev_event(str
 | |
| + 
 | |
| + 	dsa_schedule_work(&switchdev_work->work);
 | |
| + 	return NOTIFY_OK;
 | |
| +-
 | |
| +-err_fdb_work_init:
 | |
| +-	kfree(switchdev_work);
 | |
| +-	return NOTIFY_BAD;
 | |
| + }
 | |
| + 
 | |
| + static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
 | |
| diff --git a/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch b/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
 | |
| new file mode 100644
 | |
| index 0000000000..48c2af770b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/773-v5.12-net-dsa-move-switchdev-event-implementation-under-th.patch
 | |
| @@ -0,0 +1,85 @@
 | |
| +From 447d290a58bd335d68f665713842365d3d6447df Mon Sep 17 00:00:00 2001
 | |
| +From: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Date: Wed, 6 Jan 2021 11:51:33 +0200
 | |
| +Subject: [PATCH] net: dsa: move switchdev event implementation under the same
 | |
| + switch/case statement
 | |
| +
 | |
| +We'll need to start listening to SWITCHDEV_FDB_{ADD,DEL}_TO_DEVICE
 | |
| +events even for interfaces where dsa_slave_dev_check returns false, so
 | |
| +we need that check inside the switch-case statement for SWITCHDEV_FDB_*.
 | |
| +
 | |
| +This movement also avoids a useless allocation / free of switchdev_work
 | |
| +on the untreated "default event" case.
 | |
| +
 | |
| +Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +---
 | |
| + net/dsa/slave.c | 35 ++++++++++++++++-------------------
 | |
| + 1 file changed, 16 insertions(+), 19 deletions(-)
 | |
| +
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2122,31 +2122,29 @@ static int dsa_slave_switchdev_event(str
 | |
| + 	struct dsa_port *dp;
 | |
| + 	int err;
 | |
| + 
 | |
| +-	if (event == SWITCHDEV_PORT_ATTR_SET) {
 | |
| ++	switch (event) {
 | |
| ++	case SWITCHDEV_PORT_ATTR_SET:
 | |
| + 		err = switchdev_handle_port_attr_set(dev, ptr,
 | |
| + 						     dsa_slave_dev_check,
 | |
| + 						     dsa_slave_port_attr_set);
 | |
| + 		return notifier_from_errno(err);
 | |
| +-	}
 | |
| +-
 | |
| +-	if (!dsa_slave_dev_check(dev))
 | |
| +-		return NOTIFY_DONE;
 | |
| ++	case SWITCHDEV_FDB_ADD_TO_DEVICE:
 | |
| ++	case SWITCHDEV_FDB_DEL_TO_DEVICE:
 | |
| ++		if (!dsa_slave_dev_check(dev))
 | |
| ++			return NOTIFY_DONE;
 | |
| + 
 | |
| +-	dp = dsa_slave_to_port(dev);
 | |
| ++		dp = dsa_slave_to_port(dev);
 | |
| + 
 | |
| +-	switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
 | |
| +-	if (!switchdev_work)
 | |
| +-		return NOTIFY_BAD;
 | |
| +-
 | |
| +-	INIT_WORK(&switchdev_work->work,
 | |
| +-		  dsa_slave_switchdev_event_work);
 | |
| +-	switchdev_work->ds = dp->ds;
 | |
| +-	switchdev_work->port = dp->index;
 | |
| +-	switchdev_work->event = event;
 | |
| ++		switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
 | |
| ++		if (!switchdev_work)
 | |
| ++			return NOTIFY_BAD;
 | |
| ++
 | |
| ++		INIT_WORK(&switchdev_work->work,
 | |
| ++			  dsa_slave_switchdev_event_work);
 | |
| ++		switchdev_work->ds = dp->ds;
 | |
| ++		switchdev_work->port = dp->index;
 | |
| ++		switchdev_work->event = event;
 | |
| + 
 | |
| +-	switch (event) {
 | |
| +-	case SWITCHDEV_FDB_ADD_TO_DEVICE:
 | |
| +-	case SWITCHDEV_FDB_DEL_TO_DEVICE:
 | |
| + 		fdb_info = ptr;
 | |
| + 
 | |
| + 		if (!fdb_info->added_by_user) {
 | |
| +@@ -2159,13 +2157,12 @@ static int dsa_slave_switchdev_event(str
 | |
| + 		switchdev_work->vid = fdb_info->vid;
 | |
| + 
 | |
| + 		dev_hold(dev);
 | |
| ++		dsa_schedule_work(&switchdev_work->work);
 | |
| + 		break;
 | |
| + 	default:
 | |
| +-		kfree(switchdev_work);
 | |
| + 		return NOTIFY_DONE;
 | |
| + 	}
 | |
| + 
 | |
| +-	dsa_schedule_work(&switchdev_work->work);
 | |
| + 	return NOTIFY_OK;
 | |
| + }
 | |
| + 
 | |
| diff --git a/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch b/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a1f56353ea
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/774-v5.12-net-dsa-exit-early-in-dsa_slave_switchdev_event-if-w.patch
 | |
| @@ -0,0 +1,42 @@
 | |
| +From 5fb4a451a87d8ed3363d28b63a3295399373d6c4 Mon Sep 17 00:00:00 2001
 | |
| +From: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Date: Wed, 6 Jan 2021 11:51:34 +0200
 | |
| +Subject: [PATCH] net: dsa: exit early in dsa_slave_switchdev_event if we can't
 | |
| + program the FDB
 | |
| +
 | |
| +Right now, the following would happen for a switch driver that does not
 | |
| +implement .port_fdb_add or .port_fdb_del.
 | |
| +
 | |
| +dsa_slave_switchdev_event returns NOTIFY_OK and schedules:
 | |
| +-> dsa_slave_switchdev_event_work
 | |
| +   -> dsa_port_fdb_add
 | |
| +      -> dsa_port_notify(DSA_NOTIFIER_FDB_ADD)
 | |
| +         -> dsa_switch_fdb_add
 | |
| +            -> if (!ds->ops->port_fdb_add) return -EOPNOTSUPP;
 | |
| +   -> an error is printed with dev_dbg, and
 | |
| +      dsa_fdb_offload_notify(switchdev_work) is not called.
 | |
| +
 | |
| +We can avoid scheduling the worker for nothing and say NOTIFY_DONE.
 | |
| +Because we don't call dsa_fdb_offload_notify, the static FDB entry will
 | |
| +remain just in the software bridge.
 | |
| +
 | |
| +Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +---
 | |
| + net/dsa/slave.c | 3 +++
 | |
| + 1 file changed, 3 insertions(+)
 | |
| +
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2135,6 +2135,9 @@ static int dsa_slave_switchdev_event(str
 | |
| + 
 | |
| + 		dp = dsa_slave_to_port(dev);
 | |
| + 
 | |
| ++		if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
 | |
| ++			return NOTIFY_DONE;
 | |
| ++
 | |
| + 		switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
 | |
| + 		if (!switchdev_work)
 | |
| + 			return NOTIFY_BAD;
 | |
| diff --git a/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch b/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e576ff8ce2
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/775-v5.12-net-dsa-listen-for-SWITCHDEV_-FDB-DEL-_ADD_TO_DEVICE.patch
 | |
| @@ -0,0 +1,264 @@
 | |
| +From d5f19486cee79d04c054427577ac96ed123706db Mon Sep 17 00:00:00 2001
 | |
| +From: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Date: Wed, 6 Jan 2021 11:51:35 +0200
 | |
| +Subject: [PATCH] net: dsa: listen for SWITCHDEV_{FDB,DEL}_ADD_TO_DEVICE on
 | |
| + foreign bridge neighbors
 | |
| +
 | |
| +Some DSA switches (and not only) cannot learn source MAC addresses from
 | |
| +packets injected from the CPU. They only perform hardware address
 | |
| +learning from inbound traffic.
 | |
| +
 | |
| +This can be problematic when we have a bridge spanning some DSA switch
 | |
| +ports and some non-DSA ports (which we'll call "foreign interfaces" from
 | |
| +DSA's perspective).
 | |
| +
 | |
| +There are 2 classes of problems created by the lack of learning on
 | |
| +CPU-injected traffic:
 | |
| +- excessive flooding, due to the fact that DSA treats those addresses as
 | |
| +  unknown
 | |
| +- the risk of stale routes, which can lead to temporary packet loss
 | |
| +
 | |
| +To illustrate the second class, consider the following situation, which
 | |
| +is common in production equipment (wireless access points, where there
 | |
| +is a WLAN interface and an Ethernet switch, and these form a single
 | |
| +bridging domain).
 | |
| +
 | |
| + AP 1:
 | |
| + +------------------------------------------------------------------------+
 | |
| + |                                          br0                           |
 | |
| + +------------------------------------------------------------------------+
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| + |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| +       |                                                       ^        ^
 | |
| +       |                                                       |        |
 | |
| +       |                                                       |        |
 | |
| +       |                                                    Client A  Client B
 | |
| +       |
 | |
| +       |
 | |
| +       |
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| + |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| + +------------------------------------------------------------------------+
 | |
| + |                                          br0                           |
 | |
| + +------------------------------------------------------------------------+
 | |
| + AP 2
 | |
| +
 | |
| +- br0 of AP 1 will know that Clients A and B are reachable via wlan0
 | |
| +- the hardware fdb of a DSA switch driver today is not kept in sync with
 | |
| +  the software entries on other bridge ports, so it will not know that
 | |
| +  clients A and B are reachable via the CPU port UNLESS the hardware
 | |
| +  switch itself performs SA learning from traffic injected from the CPU.
 | |
| +  Nonetheless, a substantial number of switches don't.
 | |
| +- the hardware fdb of the DSA switch on AP 2 may autonomously learn that
 | |
| +  Client A and B are reachable through swp0. Therefore, the software br0
 | |
| +  of AP 2 also may or may not learn this. In the example we're
 | |
| +  illustrating, some Ethernet traffic has been going on, and br0 from AP
 | |
| +  2 has indeed learnt that it can reach Client B through swp0.
 | |
| +
 | |
| +One of the wireless clients, say Client B, disconnects from AP 1 and
 | |
| +roams to AP 2. The topology now looks like this:
 | |
| +
 | |
| + AP 1:
 | |
| + +------------------------------------------------------------------------+
 | |
| + |                                          br0                           |
 | |
| + +------------------------------------------------------------------------+
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| + |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| +       |                                                            ^
 | |
| +       |                                                            |
 | |
| +       |                                                         Client A
 | |
| +       |
 | |
| +       |
 | |
| +       |                                                         Client B
 | |
| +       |                                                            |
 | |
| +       |                                                            v
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| + |    swp0    | |    swp1    | |    swp2    | |    swp3    | |    wlan0   |
 | |
| + +------------+ +------------+ +------------+ +------------+ +------------+
 | |
| + +------------------------------------------------------------------------+
 | |
| + |                                          br0                           |
 | |
| + +------------------------------------------------------------------------+
 | |
| + AP 2
 | |
| +
 | |
| +- br0 of AP 1 still knows that Client A is reachable via wlan0 (no change)
 | |
| +- br0 of AP 1 will (possibly) know that Client B has left wlan0. There
 | |
| +  are cases where it might never find out though. Either way, DSA today
 | |
| +  does not process that notification in any way.
 | |
| +- the hardware FDB of the DSA switch on AP 1 may learn autonomously that
 | |
| +  Client B can be reached via swp0, if it receives any packet with
 | |
| +  Client 1's source MAC address over Ethernet.
 | |
| +- the hardware FDB of the DSA switch on AP 2 still thinks that Client B
 | |
| +  can be reached via swp0. It does not know that it has roamed to wlan0,
 | |
| +  because it doesn't perform SA learning from the CPU port.
 | |
| +
 | |
| +Now Client A contacts Client B.
 | |
| +AP 1 routes the packet fine towards swp0 and delivers it on the Ethernet
 | |
| +segment.
 | |
| +AP 2 sees a frame on swp0 and its fdb says that the destination is swp0.
 | |
| +Hairpinning is disabled => drop.
 | |
| +
 | |
| +This problem comes from the fact that these switches have a 'blind spot'
 | |
| +for addresses coming from software bridging. The generic solution is not
 | |
| +to assume that hardware learning can be enabled somehow, but to listen
 | |
| +to more bridge learning events. It turns out that the bridge driver does
 | |
| +learn in software from all inbound frames, in __br_handle_local_finish.
 | |
| +A proper SWITCHDEV_FDB_ADD_TO_DEVICE notification is emitted for the
 | |
| +addresses serviced by the bridge on 'foreign' interfaces. The software
 | |
| +bridge also does the right thing on migration, by notifying that the old
 | |
| +entry is deleted, so that does not need to be special-cased in DSA. When
 | |
| +it is deleted, we just need to delete our static FDB entry towards the
 | |
| +CPU too, and wait.
 | |
| +
 | |
| +The problem is that DSA currently only cares about SWITCHDEV_FDB_ADD_TO_DEVICE
 | |
| +events received on its own interfaces, such as static FDB entries.
 | |
| +
 | |
| +Luckily we can change that, and DSA can listen to all switchdev FDB
 | |
| +add/del events in the system and figure out if those events were emitted
 | |
| +by a bridge that spans at least one of DSA's own ports. In case that is
 | |
| +true, DSA will also offload that address towards its own CPU port, in
 | |
| +the eventuality that there might be bridge clients attached to the DSA
 | |
| +switch who want to talk to the station connected to the foreign
 | |
| +interface.
 | |
| +
 | |
| +In terms of implementation, we need to keep the fdb_info->added_by_user
 | |
| +check for the case where the switchdev event was targeted directly at a
 | |
| +DSA switch port. But we don't need to look at that flag for snooped
 | |
| +events. So the check is currently too late, we need to move it earlier.
 | |
| +This also simplifies the code a bit, since we avoid uselessly allocating
 | |
| +and freeing switchdev_work.
 | |
| +
 | |
| +We could probably do some improvements in the future. For example,
 | |
| +multi-bridge support is rudimentary at the moment. If there are two
 | |
| +bridges spanning a DSA switch's ports, and both of them need to service
 | |
| +the same MAC address, then what will happen is that the migration of one
 | |
| +of those stations will trigger the deletion of the FDB entry from the
 | |
| +CPU port while it is still used by other bridge. That could be improved
 | |
| +with reference counting but is left for another time.
 | |
| +
 | |
| +This behavior needs to be enabled at driver level by setting
 | |
| +ds->assisted_learning_on_cpu_port = true. This is because we don't want
 | |
| +to inflict a potential performance penalty (accesses through
 | |
| +MDIO/I2C/SPI are expensive) to hardware that really doesn't need it
 | |
| +because address learning on the CPU port works there.
 | |
| +
 | |
| +Reported-by: DENG Qingfang <dqfext@gmail.com>
 | |
| +Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| +Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Reviewed-by: Andrew Lunn <andrew@lunn.ch>
 | |
| +Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 | |
| +---
 | |
| + include/net/dsa.h |  5 +++++
 | |
| + net/dsa/slave.c   | 66 +++++++++++++++++++++++++++++++++++++++++++++----------
 | |
| + 2 files changed, 60 insertions(+), 11 deletions(-)
 | |
| +
 | |
| +--- a/include/net/dsa.h
 | |
| ++++ b/include/net/dsa.h
 | |
| +@@ -317,6 +317,11 @@ struct dsa_switch {
 | |
| + 	 */
 | |
| + 	bool			untag_bridge_pvid;
 | |
| + 
 | |
| ++	/* Let DSA manage the FDB entries towards the CPU, based on the
 | |
| ++	 * software bridge database.
 | |
| ++	 */
 | |
| ++	bool			assisted_learning_on_cpu_port;
 | |
| ++
 | |
| + 	/* In case vlan_filtering_is_global is set, the VLAN awareness state
 | |
| + 	 * should be retrieved from here and not from the per-port settings.
 | |
| + 	 */
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2112,6 +2112,28 @@ static void dsa_slave_switchdev_event_wo
 | |
| + 		dev_put(dp->slave);
 | |
| + }
 | |
| + 
 | |
| ++static int dsa_lower_dev_walk(struct net_device *lower_dev,
 | |
| ++			      struct netdev_nested_priv *priv)
 | |
| ++{
 | |
| ++	if (dsa_slave_dev_check(lower_dev)) {
 | |
| ++		priv->data = (void *)netdev_priv(lower_dev);
 | |
| ++		return 1;
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static struct dsa_slave_priv *dsa_slave_dev_lower_find(struct net_device *dev)
 | |
| ++{
 | |
| ++	struct netdev_nested_priv priv = {
 | |
| ++		.data = NULL,
 | |
| ++	};
 | |
| ++
 | |
| ++	netdev_walk_all_lower_dev_rcu(dev, dsa_lower_dev_walk, &priv);
 | |
| ++
 | |
| ++	return (struct dsa_slave_priv *)priv.data;
 | |
| ++}
 | |
| ++
 | |
| + /* Called under rcu_read_lock() */
 | |
| + static int dsa_slave_switchdev_event(struct notifier_block *unused,
 | |
| + 				     unsigned long event, void *ptr)
 | |
| +@@ -2130,10 +2152,37 @@ static int dsa_slave_switchdev_event(str
 | |
| + 		return notifier_from_errno(err);
 | |
| + 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
 | |
| + 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
 | |
| +-		if (!dsa_slave_dev_check(dev))
 | |
| +-			return NOTIFY_DONE;
 | |
| ++		fdb_info = ptr;
 | |
| ++
 | |
| ++		if (dsa_slave_dev_check(dev)) {
 | |
| ++			if (!fdb_info->added_by_user)
 | |
| ++				return NOTIFY_OK;
 | |
| ++
 | |
| ++			dp = dsa_slave_to_port(dev);
 | |
| ++		} else {
 | |
| ++			/* Snoop addresses learnt on foreign interfaces
 | |
| ++			 * bridged with us, for switches that don't
 | |
| ++			 * automatically learn SA from CPU-injected traffic
 | |
| ++			 */
 | |
| ++			struct net_device *br_dev;
 | |
| ++			struct dsa_slave_priv *p;
 | |
| ++
 | |
| ++			br_dev = netdev_master_upper_dev_get_rcu(dev);
 | |
| ++			if (!br_dev)
 | |
| ++				return NOTIFY_DONE;
 | |
| ++
 | |
| ++			if (!netif_is_bridge_master(br_dev))
 | |
| ++				return NOTIFY_DONE;
 | |
| ++
 | |
| ++			p = dsa_slave_dev_lower_find(br_dev);
 | |
| ++			if (!p)
 | |
| ++				return NOTIFY_DONE;
 | |
| + 
 | |
| +-		dp = dsa_slave_to_port(dev);
 | |
| ++			dp = p->dp->cpu_dp;
 | |
| ++
 | |
| ++			if (!dp->ds->assisted_learning_on_cpu_port)
 | |
| ++				return NOTIFY_DONE;
 | |
| ++		}
 | |
| + 
 | |
| + 		if (!dp->ds->ops->port_fdb_add || !dp->ds->ops->port_fdb_del)
 | |
| + 			return NOTIFY_DONE;
 | |
| +@@ -2148,18 +2197,13 @@ static int dsa_slave_switchdev_event(str
 | |
| + 		switchdev_work->port = dp->index;
 | |
| + 		switchdev_work->event = event;
 | |
| + 
 | |
| +-		fdb_info = ptr;
 | |
| +-
 | |
| +-		if (!fdb_info->added_by_user) {
 | |
| +-			kfree(switchdev_work);
 | |
| +-			return NOTIFY_OK;
 | |
| +-		}
 | |
| +-
 | |
| + 		ether_addr_copy(switchdev_work->addr,
 | |
| + 				fdb_info->addr);
 | |
| + 		switchdev_work->vid = fdb_info->vid;
 | |
| + 
 | |
| +-		dev_hold(dev);
 | |
| ++		/* Hold a reference on the slave for dsa_fdb_offload_notify */
 | |
| ++		if (dsa_is_user_port(dp->ds, dp->index))
 | |
| ++			dev_hold(dev);
 | |
| + 		dsa_schedule_work(&switchdev_work->work);
 | |
| + 		break;
 | |
| + 	default:
 | |
| diff --git a/target/linux/generic/backport-5.10/780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch b/target/linux/generic/backport-5.10/780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch
 | |
| new file mode 100644
 | |
| index 0000000000..951ae9c664
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/780-net-dsa-mt7530-setup-core-clock-even-in-TRGMII-mode.patch
 | |
| @@ -0,0 +1,84 @@
 | |
| +From c3b8e07909dbe67b0d580416c1a5257643a73be7 Mon Sep 17 00:00:00 2001
 | |
| +From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
 | |
| +Date: Fri, 12 Mar 2021 00:07:03 -0800
 | |
| +Subject: [PATCH] net: dsa: mt7530: setup core clock even in TRGMII mode
 | |
| +
 | |
| +A recent change to MIPS ralink reset logic made it so mt7530 actually
 | |
| +resets the switch on platforms such as mt7621 (where bit 2 is the reset
 | |
| +line for the switch). That exposed an issue where the switch would not
 | |
| +function properly in TRGMII mode after a reset.
 | |
| +
 | |
| +Reconfigure core clock in TRGMII mode to fix the issue.
 | |
| +
 | |
| +Tested on Ubiquiti ER-X (MT7621) with TRGMII mode enabled.
 | |
| +
 | |
| +Fixes: 3f9ef7785a9c ("MIPS: ralink: manage low reset lines")
 | |
| +Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
 | |
| +Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| +---
 | |
| + drivers/net/dsa/mt7530.c | 52 +++++++++++++++++++---------------------
 | |
| + 1 file changed, 25 insertions(+), 27 deletions(-)
 | |
| +
 | |
| +--- a/drivers/net/dsa/mt7530.c
 | |
| ++++ b/drivers/net/dsa/mt7530.c
 | |
| +@@ -435,34 +435,32 @@ mt7530_pad_clk_setup(struct dsa_switch *
 | |
| + 			     TD_DM_DRVP(8) | TD_DM_DRVN(8));
 | |
| + 
 | |
| + 	/* Setup core clock for MT7530 */
 | |
| +-	if (!trgint) {
 | |
| +-		/* Disable MT7530 core clock */
 | |
| +-		core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
 | |
| +-
 | |
| +-		/* Disable PLL, since phy_device has not yet been created
 | |
| +-		 * provided for phy_[read,write]_mmd_indirect is called, we
 | |
| +-		 * provide our own core_write_mmd_indirect to complete this
 | |
| +-		 * function.
 | |
| +-		 */
 | |
| +-		core_write_mmd_indirect(priv,
 | |
| +-					CORE_GSWPLL_GRP1,
 | |
| +-					MDIO_MMD_VEND2,
 | |
| +-					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));
 | |
| +-
 | |
| +-		/* Enable MT7530 core clock */
 | |
| +-		core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
 | |
| +-	}
 | |
| ++	/* Disable MT7530 core clock */
 | |
| ++	core_clear(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
 | |
| ++
 | |
| ++	/* Disable PLL, since phy_device has not yet been created
 | |
| ++	 * provided for phy_[read,write]_mmd_indirect is called, we
 | |
| ++	 * provide our own core_write_mmd_indirect to complete this
 | |
| ++	 * function.
 | |
| ++	 */
 | |
| ++	core_write_mmd_indirect(priv,
 | |
| ++				CORE_GSWPLL_GRP1,
 | |
| ++				MDIO_MMD_VEND2,
 | |
| ++				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));
 | |
| ++
 | |
| ++	/* Enable MT7530 core clock */
 | |
| ++	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
 | |
| + 
 | |
| + 	/* Setup the MT7530 TRGMII Tx Clock */
 | |
| + 	core_set(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
 | |
| diff --git a/target/linux/generic/backport-5.10/800-v5.13-0001-firmware-bcm47xx_nvram-rename-finding-function-and-i.patch b/target/linux/generic/backport-5.10/800-v5.13-0001-firmware-bcm47xx_nvram-rename-finding-function-and-i.patch
 | |
| new file mode 100644
 | |
| index 0000000000..19938704b7
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/800-v5.13-0001-firmware-bcm47xx_nvram-rename-finding-function-and-i.patch
 | |
| @@ -0,0 +1,80 @@
 | |
| +From fb009cbdd0693bd633f11e99526617b3d392cfad Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Mon, 8 Mar 2021 10:03:16 +0100
 | |
| +Subject: [PATCH] firmware: bcm47xx_nvram: rename finding function and its
 | |
| + variables
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +1. Use "bcm47xx_" function name prefix for consistency
 | |
| +2. It takes flash start as argument so s/iobase/flash_start/
 | |
| +3. "off" was used for finding flash end so just call it "flash_size"
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 | |
| +---
 | |
| + drivers/firmware/broadcom/bcm47xx_nvram.c | 24 ++++++++++++-----------
 | |
| + 1 file changed, 13 insertions(+), 11 deletions(-)
 | |
| +
 | |
| +--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| ++++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| +@@ -48,11 +48,13 @@ static u32 find_nvram_size(void __iomem
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| +-/* Probe for NVRAM header */
 | |
| +-static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
 | |
| ++/**
 | |
| ++ * bcm47xx_nvram_find_and_copy - find NVRAM on flash mapping & copy it
 | |
| ++ */
 | |
| ++static int bcm47xx_nvram_find_and_copy(void __iomem *flash_start, size_t res_size)
 | |
| + {
 | |
| + 	struct nvram_header __iomem *header;
 | |
| +-	u32 off;
 | |
| ++	size_t flash_size;
 | |
| + 	u32 size;
 | |
| + 
 | |
| + 	if (nvram_len) {
 | |
| +@@ -61,25 +63,25 @@ static int nvram_find_and_copy(void __io
 | |
| + 	}
 | |
| + 
 | |
| + 	/* TODO: when nvram is on nand flash check for bad blocks first. */
 | |
| +-	off = FLASH_MIN;
 | |
| +-	while (off <= lim) {
 | |
| ++	flash_size = FLASH_MIN;
 | |
| ++	while (flash_size <= res_size) {
 | |
| + 		/* Windowed flash access */
 | |
| +-		size = find_nvram_size(iobase + off);
 | |
| ++		size = find_nvram_size(flash_start + flash_size);
 | |
| + 		if (size) {
 | |
| +-			header = (struct nvram_header *)(iobase + off - size);
 | |
| ++			header = (struct nvram_header *)(flash_start + flash_size - size);
 | |
| + 			goto found;
 | |
| + 		}
 | |
| +-		off <<= 1;
 | |
| ++		flash_size <<= 1;
 | |
| + 	}
 | |
| + 
 | |
| + 	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
 | |
| +-	header = (struct nvram_header *)(iobase + 4096);
 | |
| ++	header = (struct nvram_header *)(flash_start + 4096);
 | |
| + 	if (header->magic == NVRAM_MAGIC) {
 | |
| + 		size = NVRAM_SPACE;
 | |
| + 		goto found;
 | |
| + 	}
 | |
| + 
 | |
| +-	header = (struct nvram_header *)(iobase + 1024);
 | |
| ++	header = (struct nvram_header *)(flash_start + 1024);
 | |
| + 	if (header->magic == NVRAM_MAGIC) {
 | |
| + 		size = NVRAM_SPACE;
 | |
| + 		goto found;
 | |
| +@@ -124,7 +126,7 @@ int bcm47xx_nvram_init_from_mem(u32 base
 | |
| + 	if (!iobase)
 | |
| + 		return -ENOMEM;
 | |
| + 
 | |
| +-	err = nvram_find_and_copy(iobase, lim);
 | |
| ++	err = bcm47xx_nvram_find_and_copy(iobase, lim);
 | |
| + 
 | |
| + 	iounmap(iobase);
 | |
| + 
 | |
| diff --git a/target/linux/generic/backport-5.10/800-v5.13-0002-firmware-bcm47xx_nvram-add-helper-checking-for-NVRAM.patch b/target/linux/generic/backport-5.10/800-v5.13-0002-firmware-bcm47xx_nvram-add-helper-checking-for-NVRAM.patch
 | |
| new file mode 100644
 | |
| index 0000000000..6ab072883d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/800-v5.13-0002-firmware-bcm47xx_nvram-add-helper-checking-for-NVRAM.patch
 | |
| @@ -0,0 +1,90 @@
 | |
| +From 0a24b51a3264a3f942a75025ea5ff6133c8989b0 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Mon, 8 Mar 2021 10:03:17 +0100
 | |
| +Subject: [PATCH] firmware: bcm47xx_nvram: add helper checking for NVRAM
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This avoids duplicating code doing casting and checking for NVRAM magic.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 | |
| +---
 | |
| + drivers/firmware/broadcom/bcm47xx_nvram.c | 30 ++++++++++++++---------
 | |
| + 1 file changed, 18 insertions(+), 12 deletions(-)
 | |
| +
 | |
| +--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| ++++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| +@@ -34,14 +34,20 @@ static char nvram_buf[NVRAM_SPACE];
 | |
| + static size_t nvram_len;
 | |
| + static const u32 nvram_sizes[] = {0x6000, 0x8000, 0xF000, 0x10000};
 | |
| + 
 | |
| ++/**
 | |
| ++ * bcm47xx_nvram_is_valid - check for a valid NVRAM at specified memory
 | |
| ++ */
 | |
| ++static bool bcm47xx_nvram_is_valid(void __iomem *nvram)
 | |
| ++{
 | |
| ++	return ((struct nvram_header *)nvram)->magic == NVRAM_MAGIC;
 | |
| ++}
 | |
| ++
 | |
| + static u32 find_nvram_size(void __iomem *end)
 | |
| + {
 | |
| +-	struct nvram_header __iomem *header;
 | |
| + 	int i;
 | |
| + 
 | |
| + 	for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
 | |
| +-		header = (struct nvram_header *)(end - nvram_sizes[i]);
 | |
| +-		if (header->magic == NVRAM_MAGIC)
 | |
| ++		if (bcm47xx_nvram_is_valid(end - nvram_sizes[i]))
 | |
| + 			return nvram_sizes[i];
 | |
| + 	}
 | |
| + 
 | |
| +@@ -55,6 +61,7 @@ static int bcm47xx_nvram_find_and_copy(v
 | |
| + {
 | |
| + 	struct nvram_header __iomem *header;
 | |
| + 	size_t flash_size;
 | |
| ++	size_t offset;
 | |
| + 	u32 size;
 | |
| + 
 | |
| + 	if (nvram_len) {
 | |
| +@@ -68,31 +75,30 @@ static int bcm47xx_nvram_find_and_copy(v
 | |
| + 		/* Windowed flash access */
 | |
| + 		size = find_nvram_size(flash_start + flash_size);
 | |
| + 		if (size) {
 | |
| +-			header = (struct nvram_header *)(flash_start + flash_size - size);
 | |
| ++			offset = flash_size - size;
 | |
| + 			goto found;
 | |
| + 		}
 | |
| + 		flash_size <<= 1;
 | |
| + 	}
 | |
| + 
 | |
| + 	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
 | |
| +-	header = (struct nvram_header *)(flash_start + 4096);
 | |
| +-	if (header->magic == NVRAM_MAGIC) {
 | |
| +-		size = NVRAM_SPACE;
 | |
| ++
 | |
| ++	offset = 4096;
 | |
| ++	if (bcm47xx_nvram_is_valid(flash_start + offset))
 | |
| + 		goto found;
 | |
| +-	}
 | |
| + 
 | |
| +-	header = (struct nvram_header *)(flash_start + 1024);
 | |
| +-	if (header->magic == NVRAM_MAGIC) {
 | |
| +-		size = NVRAM_SPACE;
 | |
| ++	offset = 1024;
 | |
| ++	if (bcm47xx_nvram_is_valid(flash_start + offset))
 | |
| + 		goto found;
 | |
| +-	}
 | |
| + 
 | |
| + 	pr_err("no nvram found\n");
 | |
| + 	return -ENXIO;
 | |
| + 
 | |
| + found:
 | |
| ++	header = (struct nvram_header *)(flash_start + offset);
 | |
| + 	__ioread32_copy(nvram_buf, header, sizeof(*header) / 4);
 | |
| + 	nvram_len = ((struct nvram_header *)(nvram_buf))->len;
 | |
| ++	size = res_size - offset;
 | |
| + 	if (nvram_len > size) {
 | |
| + 		pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n");
 | |
| + 		nvram_len = size;
 | |
| diff --git a/target/linux/generic/backport-5.10/800-v5.13-0003-firmware-bcm47xx_nvram-extract-code-copying-NVRAM.patch b/target/linux/generic/backport-5.10/800-v5.13-0003-firmware-bcm47xx_nvram-extract-code-copying-NVRAM.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a1351f1197
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/800-v5.13-0003-firmware-bcm47xx_nvram-extract-code-copying-NVRAM.patch
 | |
| @@ -0,0 +1,80 @@
 | |
| +From 298923cf999cecd2ef06df126f85a3d68da8c4d8 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Mon, 8 Mar 2021 10:03:18 +0100
 | |
| +Subject: [PATCH] firmware: bcm47xx_nvram: extract code copying NVRAM
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This simplifies function finding NVRAM. It doesn't directly deal with
 | |
| +NVRAM structure anymore and is a bit smaller.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 | |
| +---
 | |
| + drivers/firmware/broadcom/bcm47xx_nvram.c | 43 +++++++++++++----------
 | |
| + 1 file changed, 25 insertions(+), 18 deletions(-)
 | |
| +
 | |
| +--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| ++++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| +@@ -55,11 +55,34 @@ static u32 find_nvram_size(void __iomem
 | |
| + }
 | |
| + 
 | |
| + /**
 | |
| ++ * bcm47xx_nvram_copy - copy NVRAM to internal buffer
 | |
| ++ */
 | |
| ++static void bcm47xx_nvram_copy(void __iomem *nvram_start, size_t res_size)
 | |
| ++{
 | |
| ++	struct nvram_header __iomem *header = nvram_start;
 | |
| ++	size_t copy_size;
 | |
| ++
 | |
| ++	copy_size = header->len;
 | |
| ++	if (copy_size > res_size) {
 | |
| ++		pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n");
 | |
| ++		copy_size = res_size;
 | |
| ++	}
 | |
| ++	if (copy_size >= NVRAM_SPACE) {
 | |
| ++		pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
 | |
| ++		       copy_size, NVRAM_SPACE - 1);
 | |
| ++		copy_size = NVRAM_SPACE - 1;
 | |
| ++	}
 | |
| ++
 | |
| ++	__ioread32_copy(nvram_buf, nvram_start, DIV_ROUND_UP(copy_size, 4));
 | |
| ++	nvram_buf[NVRAM_SPACE - 1] = '\0';
 | |
| ++	nvram_len = copy_size;
 | |
| ++}
 | |
| ++
 | |
| ++/**
 | |
| +  * bcm47xx_nvram_find_and_copy - find NVRAM on flash mapping & copy it
 | |
| +  */
 | |
| + static int bcm47xx_nvram_find_and_copy(void __iomem *flash_start, size_t res_size)
 | |
| + {
 | |
| +-	struct nvram_header __iomem *header;
 | |
| + 	size_t flash_size;
 | |
| + 	size_t offset;
 | |
| + 	u32 size;
 | |
| +@@ -95,23 +118,7 @@ static int bcm47xx_nvram_find_and_copy(v
 | |
| + 	return -ENXIO;
 | |
| + 
 | |
| + found:
 | |
| +-	header = (struct nvram_header *)(flash_start + offset);
 | |
| +-	__ioread32_copy(nvram_buf, header, sizeof(*header) / 4);
 | |
| +-	nvram_len = ((struct nvram_header *)(nvram_buf))->len;
 | |
| +-	size = res_size - offset;
 | |
| +-	if (nvram_len > size) {
 | |
| +-		pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n");
 | |
| +-		nvram_len = size;
 | |
| +-	}
 | |
| +-	if (nvram_len >= NVRAM_SPACE) {
 | |
| +-		pr_err("nvram on flash (%zu bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
 | |
| +-		       nvram_len, NVRAM_SPACE - 1);
 | |
| +-		nvram_len = NVRAM_SPACE - 1;
 | |
| +-	}
 | |
| +-	/* proceed reading data after header */
 | |
| +-	__ioread32_copy(nvram_buf + sizeof(*header), header + 1,
 | |
| +-			DIV_ROUND_UP(nvram_len, 4));
 | |
| +-	nvram_buf[NVRAM_SPACE - 1] = '\0';
 | |
| ++	bcm47xx_nvram_copy(flash_start + offset, res_size - offset);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| diff --git a/target/linux/generic/backport-5.10/800-v5.13-0004-firmware-bcm47xx_nvram-look-for-NVRAM-with-for-inste.patch b/target/linux/generic/backport-5.10/800-v5.13-0004-firmware-bcm47xx_nvram-look-for-NVRAM-with-for-inste.patch
 | |
| new file mode 100644
 | |
| index 0000000000..059a13220b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/800-v5.13-0004-firmware-bcm47xx_nvram-look-for-NVRAM-with-for-inste.patch
 | |
| @@ -0,0 +1,37 @@
 | |
| +From 98b68324f67236e8c9152976535dc1f27fb67ba8 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Mon, 8 Mar 2021 10:03:19 +0100
 | |
| +Subject: [PATCH] firmware: bcm47xx_nvram: look for NVRAM with for instead of
 | |
| + while
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This loop requires variable initialization, stop condition and post
 | |
| +iteration increment. It's pretty much a for loop definition.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 | |
| +---
 | |
| + drivers/firmware/broadcom/bcm47xx_nvram.c | 4 +---
 | |
| + 1 file changed, 1 insertion(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| ++++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| +@@ -93,15 +93,13 @@ static int bcm47xx_nvram_find_and_copy(v
 | |
| + 	}
 | |
| + 
 | |
| + 	/* TODO: when nvram is on nand flash check for bad blocks first. */
 | |
| +-	flash_size = FLASH_MIN;
 | |
| +-	while (flash_size <= res_size) {
 | |
| ++	for (flash_size = FLASH_MIN; flash_size <= res_size; flash_size <<= 1) {
 | |
| + 		/* Windowed flash access */
 | |
| + 		size = find_nvram_size(flash_start + flash_size);
 | |
| + 		if (size) {
 | |
| + 			offset = flash_size - size;
 | |
| + 			goto found;
 | |
| + 		}
 | |
| +-		flash_size <<= 1;
 | |
| + 	}
 | |
| + 
 | |
| + 	/* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
 | |
| diff --git a/target/linux/generic/backport-5.10/800-v5.13-0005-firmware-bcm47xx_nvram-inline-code-checking-NVRAM-si.patch b/target/linux/generic/backport-5.10/800-v5.13-0005-firmware-bcm47xx_nvram-inline-code-checking-NVRAM-si.patch
 | |
| new file mode 100644
 | |
| index 0000000000..21d250049e
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/800-v5.13-0005-firmware-bcm47xx_nvram-inline-code-checking-NVRAM-si.patch
 | |
| @@ -0,0 +1,70 @@
 | |
| +From f52da4ccfec9192e17f5c16260dfdd6d3ea76f65 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Date: Mon, 8 Mar 2021 10:03:20 +0100
 | |
| +Subject: [PATCH] firmware: bcm47xx_nvram: inline code checking NVRAM size
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +Separated function was not improving code quality much (or at all).
 | |
| +Moreover it expected possible flash end address as argument and it was
 | |
| +returning NVRAM size.
 | |
| +
 | |
| +The new code always operates on offsets which means less logic and less
 | |
| +calculations.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 | |
| +---
 | |
| + drivers/firmware/broadcom/bcm47xx_nvram.c | 25 +++++++----------------
 | |
| + 1 file changed, 7 insertions(+), 18 deletions(-)
 | |
| +
 | |
| +--- a/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| ++++ b/drivers/firmware/broadcom/bcm47xx_nvram.c
 | |
| +@@ -42,18 +42,6 @@ static bool bcm47xx_nvram_is_valid(void
 | |
| + 	return ((struct nvram_header *)nvram)->magic == NVRAM_MAGIC;
 | |
| + }
 | |
| + 
 | |
| +-static u32 find_nvram_size(void __iomem *end)
 | |
| +-{
 | |
| +-	int i;
 | |
| +-
 | |
| +-	for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
 | |
| +-		if (bcm47xx_nvram_is_valid(end - nvram_sizes[i]))
 | |
| +-			return nvram_sizes[i];
 | |
| +-	}
 | |
| +-
 | |
| +-	return 0;
 | |
| +-}
 | |
| +-
 | |
| + /**
 | |
| +  * bcm47xx_nvram_copy - copy NVRAM to internal buffer
 | |
| +  */
 | |
| +@@ -85,7 +73,7 @@ static int bcm47xx_nvram_find_and_copy(v
 | |
| + {
 | |
| + 	size_t flash_size;
 | |
| + 	size_t offset;
 | |
| +-	u32 size;
 | |
| ++	int i;
 | |
| + 
 | |
| + 	if (nvram_len) {
 | |
| + 		pr_warn("nvram already initialized\n");
 | |
| +@@ -93,12 +81,13 @@ static int bcm47xx_nvram_find_and_copy(v
 | |
| + 	}
 | |
| + 
 | |
| + 	/* TODO: when nvram is on nand flash check for bad blocks first. */
 | |
| ++
 | |
| ++	/* Try every possible flash size and check for NVRAM at its end */
 | |
| + 	for (flash_size = FLASH_MIN; flash_size <= res_size; flash_size <<= 1) {
 | |
| +-		/* Windowed flash access */
 | |
| +-		size = find_nvram_size(flash_start + flash_size);
 | |
| +-		if (size) {
 | |
| +-			offset = flash_size - size;
 | |
| +-			goto found;
 | |
| ++		for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
 | |
| ++			offset = flash_size - nvram_sizes[i];
 | |
| ++			if (bcm47xx_nvram_is_valid(flash_start + offset))
 | |
| ++				goto found;
 | |
| + 		}
 | |
| + 	}
 | |
| + 
 | |
| diff --git a/target/linux/generic/backport-5.10/810-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch b/target/linux/generic/backport-5.10/810-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch
 | |
| new file mode 100644
 | |
| index 0000000000..8f2021a0fc
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/810-v5.13-usb-ehci-add-spurious-flag-to-disable-overcurrent-ch.patch
 | |
| @@ -0,0 +1,88 @@
 | |
| +From 2d5ba37461013253d2ff0a3641b727fd32ea97a9 Mon Sep 17 00:00:00 2001
 | |
| +From: Florian Fainelli <florian@openwrt.org>
 | |
| +Date: Tue, 23 Feb 2021 18:44:53 +0100
 | |
| +Subject: [PATCH 1/3] usb: ehci: add spurious flag to disable overcurrent
 | |
| + checking
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This patch adds an ignore_oc flag which can be set by EHCI controller
 | |
| +not supporting or wanting to disable overcurrent checking. The EHCI
 | |
| +platform data in include/linux/usb/ehci_pdriver.h is also augmented to
 | |
| +take advantage of this new flag.
 | |
| +
 | |
| +Signed-off-by: Florian Fainelli <florian@openwrt.org>
 | |
| +Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
 | |
| +Link: https://lore.kernel.org/r/20210223174455.1378-2-noltari@gmail.com
 | |
| +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | |
| +---
 | |
| + drivers/usb/host/ehci-hcd.c      | 2 +-
 | |
| + drivers/usb/host/ehci-hub.c      | 4 ++--
 | |
| + drivers/usb/host/ehci-platform.c | 2 ++
 | |
| + drivers/usb/host/ehci.h          | 1 +
 | |
| + include/linux/usb/ehci_pdriver.h | 1 +
 | |
| + 5 files changed, 7 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/drivers/usb/host/ehci-hcd.c
 | |
| ++++ b/drivers/usb/host/ehci-hcd.c
 | |
| +@@ -651,7 +651,7 @@ static int ehci_run (struct usb_hcd *hcd
 | |
| + 		"USB %x.%x started, EHCI %x.%02x%s\n",
 | |
| + 		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
 | |
| + 		temp >> 8, temp & 0xff,
 | |
| +-		ignore_oc ? ", overcurrent ignored" : "");
 | |
| ++		(ignore_oc || ehci->spurious_oc) ? ", overcurrent ignored" : "");
 | |
| + 
 | |
| + 	ehci_writel(ehci, INTR_MASK,
 | |
| + 		    &ehci->regs->intr_enable); /* Turn On Interrupts */
 | |
| +--- a/drivers/usb/host/ehci-hub.c
 | |
| ++++ b/drivers/usb/host/ehci-hub.c
 | |
| +@@ -643,7 +643,7 @@ ehci_hub_status_data (struct usb_hcd *hc
 | |
| + 	 * always set, seem to clear PORT_OCC and PORT_CSC when writing to
 | |
| + 	 * PORT_POWER; that's surprising, but maybe within-spec.
 | |
| + 	 */
 | |
| +-	if (!ignore_oc)
 | |
| ++	if (!ignore_oc && !ehci->spurious_oc)
 | |
| + 		mask = PORT_CSC | PORT_PEC | PORT_OCC;
 | |
| + 	else
 | |
| + 		mask = PORT_CSC | PORT_PEC;
 | |
| +@@ -1013,7 +1013,7 @@ int ehci_hub_control(
 | |
| + 		if (temp & PORT_PEC)
 | |
| + 			status |= USB_PORT_STAT_C_ENABLE << 16;
 | |
| + 
 | |
| +-		if ((temp & PORT_OCC) && !ignore_oc){
 | |
| ++		if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){
 | |
| + 			status |= USB_PORT_STAT_C_OVERCURRENT << 16;
 | |
| + 
 | |
| + 			/*
 | |
| +--- a/drivers/usb/host/ehci-platform.c
 | |
| ++++ b/drivers/usb/host/ehci-platform.c
 | |
| +@@ -327,6 +327,8 @@ static int ehci_platform_probe(struct pl
 | |
| + 		hcd->has_tt = 1;
 | |
| + 	if (pdata->reset_on_resume)
 | |
| + 		priv->reset_on_resume = true;
 | |
| ++	if (pdata->spurious_oc)
 | |
| ++		ehci->spurious_oc = 1;
 | |
| + 
 | |
| + #ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
 | |
| + 	if (ehci->big_endian_mmio) {
 | |
| +--- a/drivers/usb/host/ehci.h
 | |
| ++++ b/drivers/usb/host/ehci.h
 | |
| +@@ -218,6 +218,7 @@ struct ehci_hcd {			/* one per controlle
 | |
| + 	unsigned		frame_index_bug:1; /* MosChip (AKA NetMos) */
 | |
| + 	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */
 | |
| + 	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */
 | |
| ++	unsigned		spurious_oc:1;
 | |
| + 
 | |
| + 	/* required for usb32 quirk */
 | |
| + 	#define OHCI_CTRL_HCFS          (3 << 6)
 | |
| +--- a/include/linux/usb/ehci_pdriver.h
 | |
| ++++ b/include/linux/usb/ehci_pdriver.h
 | |
| +@@ -50,6 +50,7 @@ struct usb_ehci_pdata {
 | |
| + 	unsigned	no_io_watchdog:1;
 | |
| + 	unsigned	reset_on_resume:1;
 | |
| + 	unsigned	dma_mask_64:1;
 | |
| ++	unsigned	spurious_oc:1;
 | |
| + 
 | |
| + 	/* Turn on all power and clocks */
 | |
| + 	int (*power_on)(struct platform_device *pdev);
 | |
| diff --git a/target/linux/generic/backport-5.10/811-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch b/target/linux/generic/backport-5.10/811-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0094d47718
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/backport-5.10/811-v5.13-usb-host-ehci-platform-add-spurious_oc-DT-support.patch
 | |
| @@ -0,0 +1,31 @@
 | |
| +From 4da57dbbffdfa7fe4e2b70b047fc5ff95ff25a3d Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
 | |
| +Date: Tue, 23 Feb 2021 18:44:55 +0100
 | |
| +Subject: [PATCH 3/3] usb: host: ehci-platform: add spurious_oc DT support
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +Over-current reporting isn't supported on some platforms such as bcm63xx.
 | |
| +These devices will incorrectly report over-current if this flag isn't properly
 | |
| +activated.
 | |
| +
 | |
| +Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
 | |
| +Link: https://lore.kernel.org/r/20210223174455.1378-4-noltari@gmail.com
 | |
| +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | |
| +---
 | |
| + drivers/usb/host/ehci-platform.c | 3 +++
 | |
| + 1 file changed, 3 insertions(+)
 | |
| +
 | |
| +--- a/drivers/usb/host/ehci-platform.c
 | |
| ++++ b/drivers/usb/host/ehci-platform.c
 | |
| +@@ -286,6 +286,9 @@ static int ehci_platform_probe(struct pl
 | |
| + 		if (of_property_read_bool(dev->dev.of_node, "big-endian"))
 | |
| + 			ehci->big_endian_mmio = ehci->big_endian_desc = 1;
 | |
| + 
 | |
| ++		if (of_property_read_bool(dev->dev.of_node, "spurious-oc"))
 | |
| ++			ehci->spurious_oc = 1;
 | |
| ++
 | |
| + 		if (of_property_read_bool(dev->dev.of_node,
 | |
| + 					  "needs-reset-on-resume"))
 | |
| + 			priv->reset_on_resume = true;
 | |
| diff --git a/target/linux/generic/config-5.10 b/target/linux/generic/config-5.10
 | |
| new file mode 100644
 | |
| index 0000000000..4eb5607f17
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/config-5.10
 | |
| @@ -0,0 +1,7062 @@
 | |
| +# CONFIG_104_QUAD_8 is not set
 | |
| +CONFIG_32BIT=y
 | |
| +CONFIG_64BIT_TIME=y
 | |
| +# CONFIG_6LOWPAN is not set
 | |
| +# CONFIG_6LOWPAN_DEBUGFS is not set
 | |
| +# CONFIG_6PACK is not set
 | |
| +# CONFIG_8139CP is not set
 | |
| +# CONFIG_8139TOO is not set
 | |
| +# CONFIG_9P_FS is not set
 | |
| +# CONFIG_AB3100_CORE is not set
 | |
| +# CONFIG_AB8500_CORE is not set
 | |
| +# CONFIG_ABP060MG is not set
 | |
| +# CONFIG_ABX500_CORE is not set
 | |
| +# CONFIG_ACCESSIBILITY is not set
 | |
| +# CONFIG_ACENIC is not set
 | |
| +# CONFIG_ACERHDF is not set
 | |
| +# CONFIG_ACER_WIRELESS is not set
 | |
| +# CONFIG_ACORN_PARTITION is not set
 | |
| +# CONFIG_ACPI_ALS is not set
 | |
| +# CONFIG_ACPI_APEI is not set
 | |
| +# CONFIG_ACPI_BUTTON is not set
 | |
| +# CONFIG_ACPI_CONFIGFS is not set
 | |
| +# CONFIG_ACPI_CUSTOM_METHOD is not set
 | |
| +# CONFIG_ACPI_EXTLOG is not set
 | |
| +# CONFIG_ACPI_HED is not set
 | |
| +# CONFIG_ACPI_NFIT is not set
 | |
| +# CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set
 | |
| +# CONFIG_ACPI_TABLE_UPGRADE is not set
 | |
| +# CONFIG_ACPI_VIDEO is not set
 | |
| +# CONFIG_AD2S1200 is not set
 | |
| +# CONFIG_AD2S1210 is not set
 | |
| +# CONFIG_AD2S90 is not set
 | |
| +# CONFIG_AD5064 is not set
 | |
| +# CONFIG_AD525X_DPOT is not set
 | |
| +# CONFIG_AD5272 is not set
 | |
| +# CONFIG_AD5360 is not set
 | |
| +# CONFIG_AD5380 is not set
 | |
| +# CONFIG_AD5421 is not set
 | |
| +# CONFIG_AD5446 is not set
 | |
| +# CONFIG_AD5449 is not set
 | |
| +# CONFIG_AD5504 is not set
 | |
| +# CONFIG_AD5592R is not set
 | |
| +# CONFIG_AD5593R is not set
 | |
| +# CONFIG_AD5624R_SPI is not set
 | |
| +# CONFIG_AD5686 is not set
 | |
| +# CONFIG_AD5686_SPI is not set
 | |
| +# CONFIG_AD5696_I2C is not set
 | |
| +# CONFIG_AD5755 is not set
 | |
| +# CONFIG_AD5758 is not set
 | |
| +# CONFIG_AD5761 is not set
 | |
| +# CONFIG_AD5764 is not set
 | |
| +# CONFIG_AD5770R is not set
 | |
| +# CONFIG_AD5791 is not set
 | |
| +# CONFIG_AD5933 is not set
 | |
| +# CONFIG_AD7091R5 is not set
 | |
| +# CONFIG_AD7124 is not set
 | |
| +# CONFIG_AD7150 is not set
 | |
| +# CONFIG_AD7152 is not set
 | |
| +# CONFIG_AD7192 is not set
 | |
| +# CONFIG_AD7266 is not set
 | |
| +# CONFIG_AD7280 is not set
 | |
| +# CONFIG_AD7291 is not set
 | |
| +# CONFIG_AD7292 is not set
 | |
| +# CONFIG_AD7298 is not set
 | |
| +# CONFIG_AD7303 is not set
 | |
| +# CONFIG_AD7476 is not set
 | |
| +# CONFIG_AD7606 is not set
 | |
| +# CONFIG_AD7606_IFACE_PARALLEL is not set
 | |
| +# CONFIG_AD7606_IFACE_SPI is not set
 | |
| +# CONFIG_AD7746 is not set
 | |
| +# CONFIG_AD7766 is not set
 | |
| +# CONFIG_AD7768_1 is not set
 | |
| +# CONFIG_AD7780 is not set
 | |
| +# CONFIG_AD7791 is not set
 | |
| +# CONFIG_AD7793 is not set
 | |
| +# CONFIG_AD7816 is not set
 | |
| +# CONFIG_AD7887 is not set
 | |
| +# CONFIG_AD7923 is not set
 | |
| +# CONFIG_AD7949 is not set
 | |
| +# CONFIG_AD799X is not set
 | |
| +# CONFIG_AD8366 is not set
 | |
| +# CONFIG_AD8801 is not set
 | |
| +# CONFIG_AD9467 is not set
 | |
| +# CONFIG_AD9523 is not set
 | |
| +# CONFIG_AD9832 is not set
 | |
| +# CONFIG_AD9834 is not set
 | |
| +# CONFIG_ADAPTEC_STARFIRE is not set
 | |
| +# CONFIG_ADE7854 is not set
 | |
| +# CONFIG_ADF4350 is not set
 | |
| +# CONFIG_ADF4371 is not set
 | |
| +# CONFIG_ADFS_FS is not set
 | |
| +# CONFIG_ADIN_PHY is not set
 | |
| +# CONFIG_ADIS16080 is not set
 | |
| +# CONFIG_ADIS16130 is not set
 | |
| +# CONFIG_ADIS16136 is not set
 | |
| +# CONFIG_ADIS16201 is not set
 | |
| +# CONFIG_ADIS16203 is not set
 | |
| +# CONFIG_ADIS16209 is not set
 | |
| +# CONFIG_ADIS16240 is not set
 | |
| +# CONFIG_ADIS16260 is not set
 | |
| +# CONFIG_ADIS16400 is not set
 | |
| +# CONFIG_ADIS16460 is not set
 | |
| +# CONFIG_ADIS16475 is not set
 | |
| +# CONFIG_ADIS16480 is not set
 | |
| +# CONFIG_ADI_AXI_ADC is not set
 | |
| +# CONFIG_ADJD_S311 is not set
 | |
| +# CONFIG_ADM6996_PHY is not set
 | |
| +# CONFIG_ADM8211 is not set
 | |
| +# CONFIG_ADT7316 is not set
 | |
| +# CONFIG_ADUX1020 is not set
 | |
| +CONFIG_ADVISE_SYSCALLS=y
 | |
| +# CONFIG_ADXL345_I2C is not set
 | |
| +# CONFIG_ADXL345_SPI is not set
 | |
| +# CONFIG_ADXL372_I2C is not set
 | |
| +# CONFIG_ADXL372_SPI is not set
 | |
| +# CONFIG_ADXRS290 is not set
 | |
| +# CONFIG_ADXRS450 is not set
 | |
| +CONFIG_AEABI=y
 | |
| +# CONFIG_AFE4403 is not set
 | |
| +# CONFIG_AFE4404 is not set
 | |
| +# CONFIG_AFFS_FS is not set
 | |
| +# CONFIG_AFS_DEBUG_CURSOR is not set
 | |
| +# CONFIG_AFS_FS is not set
 | |
| +# CONFIG_AF_KCM is not set
 | |
| +# CONFIG_AF_RXRPC is not set
 | |
| +# CONFIG_AF_RXRPC_INJECT_LOSS is not set
 | |
| +# CONFIG_AF_RXRPC_IPV6 is not set
 | |
| +# CONFIG_AGP is not set
 | |
| +# CONFIG_AHCI_CEVA is not set
 | |
| +# CONFIG_AHCI_IMX is not set
 | |
| +# CONFIG_AHCI_MVEBU is not set
 | |
| +# CONFIG_AHCI_QORIQ is not set
 | |
| +CONFIG_AIO=y
 | |
| +# CONFIG_AIRO is not set
 | |
| +# CONFIG_AIRO_CS is not set
 | |
| +# CONFIG_AIX_PARTITION is not set
 | |
| +# CONFIG_AK09911 is not set
 | |
| +# CONFIG_AK8974 is not set
 | |
| +# CONFIG_AK8975 is not set
 | |
| +# CONFIG_AL3010 is not set
 | |
| +# CONFIG_AL3320A is not set
 | |
| +# CONFIG_ALIM7101_WDT is not set
 | |
| +CONFIG_ALLOW_DEV_COREDUMP=y
 | |
| +# CONFIG_ALTERA_MBOX is not set
 | |
| +# CONFIG_ALTERA_MSGDMA is not set
 | |
| +# CONFIG_ALTERA_STAPL is not set
 | |
| +# CONFIG_ALTERA_TSE is not set
 | |
| +# CONFIG_ALX is not set
 | |
| +# CONFIG_AL_FIC is not set
 | |
| +# CONFIG_AM2315 is not set
 | |
| +# CONFIG_AM335X_PHY_USB is not set
 | |
| +# CONFIG_AMBA_PL08X is not set
 | |
| +# CONFIG_AMD8111_ETH is not set
 | |
| +# CONFIG_AMD_MEM_ENCRYPT is not set
 | |
| +# CONFIG_AMD_PHY is not set
 | |
| +# CONFIG_AMD_XGBE is not set
 | |
| +# CONFIG_AMD_XGBE_HAVE_ECC is not set
 | |
| +# CONFIG_AMIGA_PARTITION is not set
 | |
| +# CONFIG_AMILO_RFKILL is not set
 | |
| +# CONFIG_ANDROID is not set
 | |
| +CONFIG_ANON_INODES=y
 | |
| +# CONFIG_APDS9300 is not set
 | |
| +# CONFIG_APDS9802ALS is not set
 | |
| +# CONFIG_APDS9960 is not set
 | |
| +# CONFIG_APM8018X is not set
 | |
| +# CONFIG_APM_EMULATION is not set
 | |
| +# CONFIG_APPLE_GMUX is not set
 | |
| +# CONFIG_APPLE_MFI_FASTCHARGE is not set
 | |
| +# CONFIG_APPLE_PROPERTIES is not set
 | |
| +# CONFIG_APPLICOM is not set
 | |
| +# CONFIG_AQTION is not set
 | |
| +# CONFIG_AQUANTIA_PHY is not set
 | |
| +# CONFIG_AR5523 is not set
 | |
| +# CONFIG_AR7 is not set
 | |
| +# CONFIG_AR8216_PHY is not set
 | |
| +# CONFIG_AR8216_PHY_LEDS is not set
 | |
| +# CONFIG_ARCH_ACTIONS is not set
 | |
| +# CONFIG_ARCH_AGILEX is not set
 | |
| +# CONFIG_ARCH_ALPINE is not set
 | |
| +# CONFIG_ARCH_ARTPEC is not set
 | |
| +# CONFIG_ARCH_ASPEED is not set
 | |
| +# CONFIG_ARCH_AT91 is not set
 | |
| +# CONFIG_ARCH_AXXIA is not set
 | |
| +# CONFIG_ARCH_BCM is not set
 | |
| +# CONFIG_ARCH_BCM2835 is not set
 | |
| +# CONFIG_ARCH_BCM_21664 is not set
 | |
| +# CONFIG_ARCH_BCM_23550 is not set
 | |
| +# CONFIG_ARCH_BCM_281XX is not set
 | |
| +# CONFIG_ARCH_BCM_5301X is not set
 | |
| +# CONFIG_ARCH_BCM_53573 is not set
 | |
| +# CONFIG_ARCH_BCM_63XX is not set
 | |
| +# CONFIG_ARCH_BCM_CYGNUS is not set
 | |
| +# CONFIG_ARCH_BCM_IPROC is not set
 | |
| +# CONFIG_ARCH_BCM_NSP is not set
 | |
| +# CONFIG_ARCH_BERLIN is not set
 | |
| +CONFIG_ARCH_BINFMT_ELF_STATE=y
 | |
| +# CONFIG_ARCH_BITMAIN is not set
 | |
| +# CONFIG_ARCH_BRCMSTB is not set
 | |
| +# CONFIG_ARCH_CLPS711X is not set
 | |
| +# CONFIG_ARCH_CNS3XXX is not set
 | |
| +# CONFIG_ARCH_DAVINCI is not set
 | |
| +# CONFIG_ARCH_DIGICOLOR is not set
 | |
| +# CONFIG_ARCH_DMA_ADDR_T_64BIT is not set
 | |
| +# CONFIG_ARCH_DOVE is not set
 | |
| +# CONFIG_ARCH_EBSA110 is not set
 | |
| +# CONFIG_ARCH_EP93XX is not set
 | |
| +# CONFIG_ARCH_EXYNOS is not set
 | |
| +CONFIG_ARCH_FLATMEM_ENABLE=y
 | |
| +# CONFIG_ARCH_FOOTBRIDGE is not set
 | |
| +# CONFIG_ARCH_GEMINI is not set
 | |
| +# CONFIG_ARCH_HI3xxx is not set
 | |
| +# CONFIG_ARCH_HIGHBANK is not set
 | |
| +# CONFIG_ARCH_HISI is not set
 | |
| +# CONFIG_ARCH_INTEGRATOR is not set
 | |
| +# CONFIG_ARCH_IOP13XX is not set
 | |
| +# CONFIG_ARCH_IOP32X is not set
 | |
| +# CONFIG_ARCH_IOP33X is not set
 | |
| +# CONFIG_ARCH_IXP4XX is not set
 | |
| +# CONFIG_ARCH_K3 is not set
 | |
| +# CONFIG_ARCH_KEEMBAY is not set
 | |
| +# CONFIG_ARCH_KEYSTONE is not set
 | |
| +# CONFIG_ARCH_KS8695 is not set
 | |
| +# CONFIG_ARCH_LAYERSCAPE is not set
 | |
| +# CONFIG_ARCH_LG1K is not set
 | |
| +# CONFIG_ARCH_LPC32XX is not set
 | |
| +# CONFIG_ARCH_MEDIATEK is not set
 | |
| +# CONFIG_ARCH_MESON is not set
 | |
| +# CONFIG_ARCH_MILBEAUT is not set
 | |
| +CONFIG_ARCH_MMAP_RND_BITS=8
 | |
| +CONFIG_ARCH_MMAP_RND_BITS_MAX=16
 | |
| +CONFIG_ARCH_MMAP_RND_BITS_MIN=8
 | |
| +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=16
 | |
| +CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
 | |
| +# CONFIG_ARCH_MMP is not set
 | |
| +# CONFIG_ARCH_MSTARV7 is not set
 | |
| +# CONFIG_ARCH_MULTIPLATFORM is not set
 | |
| +# CONFIG_ARCH_MULTI_V6 is not set
 | |
| +# CONFIG_ARCH_MULTI_V7 is not set
 | |
| +# CONFIG_ARCH_MV78XX0 is not set
 | |
| +# CONFIG_ARCH_MVEBU is not set
 | |
| +# CONFIG_ARCH_MXC is not set
 | |
| +# CONFIG_ARCH_MXS is not set
 | |
| +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
 | |
| +# CONFIG_ARCH_NETX is not set
 | |
| +# CONFIG_ARCH_NOMADIK is not set
 | |
| +# CONFIG_ARCH_NPCM is not set
 | |
| +# CONFIG_ARCH_NSPIRE is not set
 | |
| +# CONFIG_ARCH_OMAP is not set
 | |
| +# CONFIG_ARCH_OMAP1 is not set
 | |
| +# CONFIG_ARCH_OMAP2 is not set
 | |
| +# CONFIG_ARCH_OMAP2PLUS is not set
 | |
| +# CONFIG_ARCH_OMAP3 is not set
 | |
| +# CONFIG_ARCH_OMAP4 is not set
 | |
| +# CONFIG_ARCH_ORION5X is not set
 | |
| +# CONFIG_ARCH_OXNAS is not set
 | |
| +# CONFIG_ARCH_PICOXCELL is not set
 | |
| +# CONFIG_ARCH_PRIMA2 is not set
 | |
| +# CONFIG_ARCH_PXA is not set
 | |
| +# CONFIG_ARCH_QCOM is not set
 | |
| +# CONFIG_ARCH_RANDOM is not set
 | |
| +# CONFIG_ARCH_RDA is not set
 | |
| +# CONFIG_ARCH_REALTEK is not set
 | |
| +# CONFIG_ARCH_REALVIEW is not set
 | |
| +# CONFIG_ARCH_RENESAS is not set
 | |
| +# CONFIG_ARCH_ROCKCHIP is not set
 | |
| +# CONFIG_ARCH_RPC is not set
 | |
| +# CONFIG_ARCH_S32 is not set
 | |
| +# CONFIG_ARCH_S3C24XX is not set
 | |
| +# CONFIG_ARCH_S3C64XX is not set
 | |
| +# CONFIG_ARCH_S5PV210 is not set
 | |
| +# CONFIG_ARCH_SA1100 is not set
 | |
| +# CONFIG_ARCH_SEATTLE is not set
 | |
| +# CONFIG_ARCH_SHMOBILE is not set
 | |
| +# CONFIG_ARCH_SIRF is not set
 | |
| +# CONFIG_ARCH_SOCFPGA is not set
 | |
| +# CONFIG_ARCH_SPARX5 is not set
 | |
| +# CONFIG_ARCH_SPRD is not set
 | |
| +# CONFIG_ARCH_STI is not set
 | |
| +# CONFIG_ARCH_STM32 is not set
 | |
| +# CONFIG_ARCH_STRATIX10 is not set
 | |
| +# CONFIG_ARCH_SUNXI is not set
 | |
| +# CONFIG_ARCH_SYNQUACER is not set
 | |
| +# CONFIG_ARCH_TANGO is not set
 | |
| +# CONFIG_ARCH_TEGRA is not set
 | |
| +# CONFIG_ARCH_THUNDER is not set
 | |
| +# CONFIG_ARCH_THUNDER2 is not set
 | |
| +# CONFIG_ARCH_U300 is not set
 | |
| +# CONFIG_ARCH_U8500 is not set
 | |
| +# CONFIG_ARCH_UNIPHIER is not set
 | |
| +# CONFIG_ARCH_VERSATILE is not set
 | |
| +# CONFIG_ARCH_VEXPRESS is not set
 | |
| +# CONFIG_ARCH_VIRT is not set
 | |
| +# CONFIG_ARCH_VISCONTI is not set
 | |
| +# CONFIG_ARCH_VT8500 is not set
 | |
| +# CONFIG_ARCH_VULCAN is not set
 | |
| +# CONFIG_ARCH_W90X900 is not set
 | |
| +# CONFIG_ARCH_WANTS_THP_SWAP is not set
 | |
| +# CONFIG_ARCH_WM8505 is not set
 | |
| +# CONFIG_ARCH_WM8750 is not set
 | |
| +# CONFIG_ARCH_WM8850 is not set
 | |
| +# CONFIG_ARCH_XGENE is not set
 | |
| +# CONFIG_ARCH_ZX is not set
 | |
| +# CONFIG_ARCH_ZYNQ is not set
 | |
| +# CONFIG_ARCH_ZYNQMP is not set
 | |
| +# CONFIG_ARCNET is not set
 | |
| +# CONFIG_ARC_EMAC is not set
 | |
| +# CONFIG_ARC_IRQ_NO_AUTOSAVE is not set
 | |
| +# CONFIG_ARM64_16K_PAGES is not set
 | |
| +# CONFIG_ARM64_64K_PAGES is not set
 | |
| +# CONFIG_ARM64_AMU_EXTN is not set
 | |
| +# CONFIG_ARM64_BTI is not set
 | |
| +# CONFIG_ARM64_CRYPTO is not set
 | |
| +# CONFIG_ARM64_E0PD is not set
 | |
| +# CONFIG_ARM64_ERRATUM_1024718 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_1319367 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_1463225 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_1508412 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_1530923 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_1542419 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_819472 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_824069 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_826319 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_827319 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_832075 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_834220 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_843419 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_845719 is not set
 | |
| +# CONFIG_ARM64_ERRATUM_858921 is not set
 | |
| +# CONFIG_ARM64_HW_AFDBM is not set
 | |
| +# CONFIG_ARM64_LSE_ATOMICS is not set
 | |
| +# CONFIG_ARM64_MODULE_PLTS is not set
 | |
| +# CONFIG_ARM64_MTE is not set
 | |
| +# CONFIG_ARM64_PAN is not set
 | |
| +# CONFIG_ARM64_PMEM is not set
 | |
| +# CONFIG_ARM64_PSEUDO_NMI is not set
 | |
| +# CONFIG_ARM64_PTDUMP_DEBUGFS is not set
 | |
| +# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set
 | |
| +# CONFIG_ARM64_RAS_EXTN is not set
 | |
| +# CONFIG_ARM64_RELOC_TEST is not set
 | |
| +CONFIG_ARM64_SW_TTBR0_PAN=y
 | |
| +# CONFIG_ARM64_TLB_RANGE is not set
 | |
| +# CONFIG_ARM64_UAO is not set
 | |
| +# CONFIG_ARM64_USE_LSE_ATOMICS is not set
 | |
| +# CONFIG_ARM64_VA_BITS_48 is not set
 | |
| +# CONFIG_ARM64_VHE is not set
 | |
| +# CONFIG_ARM_APPENDED_DTB is not set
 | |
| +# CONFIG_ARM_ARCH_TIMER is not set
 | |
| +# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
 | |
| +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set
 | |
| +# CONFIG_ARM_CCI is not set
 | |
| +# CONFIG_ARM_CCI400_PMU is not set
 | |
| +# CONFIG_ARM_CCI5xx_PMU is not set
 | |
| +# CONFIG_ARM_CCI_PMU is not set
 | |
| +# CONFIG_ARM_CCN is not set
 | |
| +# CONFIG_ARM_CMN is not set
 | |
| +# CONFIG_ARM_CPUIDLE is not set
 | |
| +CONFIG_ARM_CPU_TOPOLOGY=y
 | |
| +# CONFIG_ARM_CRYPTO is not set
 | |
| +CONFIG_ARM_DMA_MEM_BUFFERABLE=y
 | |
| +# CONFIG_ARM_DSU_PMU is not set
 | |
| +# CONFIG_ARM_ERRATA_326103 is not set
 | |
| +# CONFIG_ARM_ERRATA_364296 is not set
 | |
| +# CONFIG_ARM_ERRATA_411920 is not set
 | |
| +# CONFIG_ARM_ERRATA_430973 is not set
 | |
| +# CONFIG_ARM_ERRATA_458693 is not set
 | |
| +# CONFIG_ARM_ERRATA_460075 is not set
 | |
| +# CONFIG_ARM_ERRATA_643719 is not set
 | |
| +# CONFIG_ARM_ERRATA_720789 is not set
 | |
| +# CONFIG_ARM_ERRATA_742230 is not set
 | |
| +# CONFIG_ARM_ERRATA_742231 is not set
 | |
| +# CONFIG_ARM_ERRATA_743622 is not set
 | |
| +# CONFIG_ARM_ERRATA_751472 is not set
 | |
| +# CONFIG_ARM_ERRATA_754322 is not set
 | |
| +# CONFIG_ARM_ERRATA_754327 is not set
 | |
| +# CONFIG_ARM_ERRATA_764369 is not set
 | |
| +# CONFIG_ARM_ERRATA_773022 is not set
 | |
| +# CONFIG_ARM_ERRATA_775420 is not set
 | |
| +# CONFIG_ARM_ERRATA_798181 is not set
 | |
| +# CONFIG_ARM_ERRATA_814220 is not set
 | |
| +# CONFIG_ARM_ERRATA_818325_852422 is not set
 | |
| +# CONFIG_ARM_ERRATA_821420 is not set
 | |
| +# CONFIG_ARM_ERRATA_825619 is not set
 | |
| +# CONFIG_ARM_ERRATA_852421 is not set
 | |
| +# CONFIG_ARM_ERRATA_852423 is not set
 | |
| +# CONFIG_ARM_ERRATA_857271 is not set
 | |
| +# CONFIG_ARM_ERRATA_857272 is not set
 | |
| +CONFIG_ARM_GIC_MAX_NR=1
 | |
| +# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
 | |
| +# CONFIG_ARM_KPROBES_TEST is not set
 | |
| +# CONFIG_ARM_LPAE is not set
 | |
| +# CONFIG_ARM_MHU is not set
 | |
| +# CONFIG_ARM_MODULE_PLTS is not set
 | |
| +# CONFIG_ARM_PATCH_PHYS_VIRT is not set
 | |
| +# CONFIG_ARM_PSCI is not set
 | |
| +# CONFIG_ARM_PSCI_CHECKER is not set
 | |
| +# CONFIG_ARM_PSCI_CPUIDLE is not set
 | |
| +# CONFIG_ARM_PTDUMP_DEBUGFS is not set
 | |
| +# CONFIG_ARM_SBSA_WATCHDOG is not set
 | |
| +# CONFIG_ARM_SCPI_PROTOCOL is not set
 | |
| +# CONFIG_ARM_SDE_INTERFACE is not set
 | |
| +# CONFIG_ARM_SMCCC_SOC_ID is not set
 | |
| +# CONFIG_ARM_SMC_WATCHDOG is not set
 | |
| +# CONFIG_ARM_SP805_WATCHDOG is not set
 | |
| +# CONFIG_ARM_SPE_PMU is not set
 | |
| +# CONFIG_ARM_THUMBEE is not set
 | |
| +# CONFIG_ARM_TIMER_SP804 is not set
 | |
| +# CONFIG_ARM_UNWIND is not set
 | |
| +# CONFIG_ARM_VIRT_EXT is not set
 | |
| +# CONFIG_AS3935 is not set
 | |
| +# CONFIG_AS73211 is not set
 | |
| +# CONFIG_ASM9260_TIMER is not set
 | |
| +# CONFIG_ASUS_LAPTOP is not set
 | |
| +# CONFIG_ASUS_WIRELESS is not set
 | |
| +# CONFIG_ASYMMETRIC_KEY_TYPE is not set
 | |
| +# CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE is not set
 | |
| +# CONFIG_ASYNC_RAID6_TEST is not set
 | |
| +# CONFIG_ASYNC_TX_DMA is not set
 | |
| +# CONFIG_AT76C50X_USB is not set
 | |
| +# CONFIG_AT803X_PHY is not set
 | |
| +# CONFIG_AT91_SAMA5D2_ADC is not set
 | |
| +# CONFIG_ATA is not set
 | |
| +# CONFIG_ATAGS is not set
 | |
| +CONFIG_ATAGS_PROC=y
 | |
| +# CONFIG_ATALK is not set
 | |
| +# CONFIG_ATARI_PARTITION is not set
 | |
| +# CONFIG_ATA_ACPI is not set
 | |
| +CONFIG_ATA_BMDMA=y
 | |
| +# CONFIG_ATA_FORCE is not set
 | |
| +# CONFIG_ATA_GENERIC is not set
 | |
| +# CONFIG_ATA_LEDS is not set
 | |
| +# CONFIG_ATA_NONSTANDARD is not set
 | |
| +# CONFIG_ATA_OVER_ETH is not set
 | |
| +# CONFIG_ATA_PIIX is not set
 | |
| +CONFIG_ATA_SFF=y
 | |
| +# CONFIG_ATA_VERBOSE_ERROR is not set
 | |
| +# CONFIG_ATH10K is not set
 | |
| +# CONFIG_ATH25 is not set
 | |
| +# CONFIG_ATH5K is not set
 | |
| +# CONFIG_ATH6KL is not set
 | |
| +# CONFIG_ATH79 is not set
 | |
| +# CONFIG_ATH9K is not set
 | |
| +# CONFIG_ATH9K_HTC is not set
 | |
| +# CONFIG_ATH_DEBUG is not set
 | |
| +# CONFIG_ATL1 is not set
 | |
| +# CONFIG_ATL1C is not set
 | |
| +# CONFIG_ATL1E is not set
 | |
| +# CONFIG_ATL2 is not set
 | |
| +# CONFIG_ATLAS_EZO_SENSOR is not set
 | |
| +# CONFIG_ATLAS_PH_SENSOR is not set
 | |
| +# CONFIG_ATM is not set
 | |
| +# CONFIG_ATMEL is not set
 | |
| +# CONFIG_ATMEL_PIT is not set
 | |
| +# CONFIG_ATMEL_SSC is not set
 | |
| +# CONFIG_ATM_AMBASSADOR is not set
 | |
| +# CONFIG_ATM_BR2684 is not set
 | |
| +CONFIG_ATM_BR2684_IPFILTER=y
 | |
| +# CONFIG_ATM_CLIP is not set
 | |
| +CONFIG_ATM_CLIP_NO_ICMP=y
 | |
| +# CONFIG_ATM_DRIVERS is not set
 | |
| +# CONFIG_ATM_DUMMY is not set
 | |
| +# CONFIG_ATM_ENI is not set
 | |
| +# CONFIG_ATM_FIRESTREAM is not set
 | |
| +# CONFIG_ATM_FORE200E is not set
 | |
| +# CONFIG_ATM_HE is not set
 | |
| +# CONFIG_ATM_HORIZON is not set
 | |
| +# CONFIG_ATM_IA is not set
 | |
| +# CONFIG_ATM_IDT77252 is not set
 | |
| +# CONFIG_ATM_LANAI is not set
 | |
| +# CONFIG_ATM_LANE is not set
 | |
| +# CONFIG_ATM_MPOA is not set
 | |
| +# CONFIG_ATM_NICSTAR is not set
 | |
| +# CONFIG_ATM_SOLOS is not set
 | |
| +# CONFIG_ATM_TCP is not set
 | |
| +# CONFIG_ATM_ZATM is not set
 | |
| +# CONFIG_ATOMIC64_SELFTEST is not set
 | |
| +# CONFIG_ATP is not set
 | |
| +# CONFIG_AUDIT is not set
 | |
| +# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set
 | |
| +# CONFIG_AURORA_NB8800 is not set
 | |
| +# CONFIG_AUTOFS4_FS is not set
 | |
| +# CONFIG_AUTOFS_FS is not set
 | |
| +# CONFIG_AUTO_ZRELADDR is not set
 | |
| +# CONFIG_AUXDISPLAY is not set
 | |
| +# CONFIG_AX25 is not set
 | |
| +# CONFIG_AX25_DAMA_SLAVE is not set
 | |
| +# CONFIG_AX88796 is not set
 | |
| +# CONFIG_AX88796B_PHY is not set
 | |
| +# CONFIG_AXP20X_ADC is not set
 | |
| +# CONFIG_AXP20X_POWER is not set
 | |
| +# CONFIG_AXP288_ADC is not set
 | |
| +# CONFIG_AXP288_FUEL_GAUGE is not set
 | |
| +# CONFIG_B43 is not set
 | |
| +# CONFIG_B43LEGACY is not set
 | |
| +# CONFIG_B44 is not set
 | |
| +# CONFIG_B53 is not set
 | |
| +# CONFIG_BACKLIGHT_ADP8860 is not set
 | |
| +# CONFIG_BACKLIGHT_ADP8870 is not set
 | |
| +# CONFIG_BACKLIGHT_APPLE is not set
 | |
| +# CONFIG_BACKLIGHT_ARCXCNN is not set
 | |
| +# CONFIG_BACKLIGHT_BD6107 is not set
 | |
| +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
 | |
| +# CONFIG_BACKLIGHT_GENERIC is not set
 | |
| +# CONFIG_BACKLIGHT_GPIO is not set
 | |
| +# CONFIG_BACKLIGHT_KTD253 is not set
 | |
| +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 | |
| +# CONFIG_BACKLIGHT_LED is not set
 | |
| +# CONFIG_BACKLIGHT_LM3630A is not set
 | |
| +# CONFIG_BACKLIGHT_LM3639 is not set
 | |
| +# CONFIG_BACKLIGHT_LP855X is not set
 | |
| +# CONFIG_BACKLIGHT_LV5207LP is not set
 | |
| +# CONFIG_BACKLIGHT_PANDORA is not set
 | |
| +# CONFIG_BACKLIGHT_PM8941_WLED is not set
 | |
| +# CONFIG_BACKLIGHT_PWM is not set
 | |
| +# CONFIG_BACKLIGHT_QCOM_WLED is not set
 | |
| +# CONFIG_BACKLIGHT_RPI is not set
 | |
| +# CONFIG_BACKLIGHT_SAHARA is not set
 | |
| +# CONFIG_BACKTRACE_SELF_TEST is not set
 | |
| +# CONFIG_BAREUDP is not set
 | |
| +CONFIG_BASE_FULL=y
 | |
| +CONFIG_BASE_SMALL=0
 | |
| +# CONFIG_BATMAN_ADV is not set
 | |
| +# CONFIG_BATTERY_BQ27XXX is not set
 | |
| +# CONFIG_BATTERY_BQ27XXX_HDQ is not set
 | |
| +# CONFIG_BATTERY_CW2015 is not set
 | |
| +# CONFIG_BATTERY_DS2760 is not set
 | |
| +# CONFIG_BATTERY_DS2780 is not set
 | |
| +# CONFIG_BATTERY_DS2781 is not set
 | |
| +# CONFIG_BATTERY_DS2782 is not set
 | |
| +# CONFIG_BATTERY_GAUGE_LTC2941 is not set
 | |
| +# CONFIG_BATTERY_GOLDFISH is not set
 | |
| +# CONFIG_BATTERY_LEGO_EV3 is not set
 | |
| +# CONFIG_BATTERY_MAX17040 is not set
 | |
| +# CONFIG_BATTERY_MAX17042 is not set
 | |
| +# CONFIG_BATTERY_MAX1721X is not set
 | |
| +# CONFIG_BATTERY_SBS is not set
 | |
| +# CONFIG_BAYCOM_EPP is not set
 | |
| +# CONFIG_BAYCOM_PAR is not set
 | |
| +# CONFIG_BAYCOM_SER_FDX is not set
 | |
| +# CONFIG_BAYCOM_SER_HDX is not set
 | |
| +# CONFIG_BCACHE is not set
 | |
| +# CONFIG_BCM47XX is not set
 | |
| +# CONFIG_BCM54140_PHY is not set
 | |
| +# CONFIG_BCM63XX is not set
 | |
| +# CONFIG_BCM63XX_PHY is not set
 | |
| +# CONFIG_BCM7038_WDT is not set
 | |
| +# CONFIG_BCM7XXX_PHY is not set
 | |
| +# CONFIG_BCM84881_PHY is not set
 | |
| +# CONFIG_BCM87XX_PHY is not set
 | |
| +# CONFIG_BCMA is not set
 | |
| +# CONFIG_BCMA_DRIVER_GPIO is not set
 | |
| +CONFIG_BCMA_POSSIBLE=y
 | |
| +# CONFIG_BCMGENET is not set
 | |
| +# CONFIG_BCM_IPROC_ADC is not set
 | |
| +# CONFIG_BCM_KONA_USB2_PHY is not set
 | |
| +# CONFIG_BCM_SBA_RAID is not set
 | |
| +# CONFIG_BDI_SWITCH is not set
 | |
| +# CONFIG_BE2ISCSI is not set
 | |
| +# CONFIG_BE2NET is not set
 | |
| +# CONFIG_BEFS_FS is not set
 | |
| +# CONFIG_BFS_FS is not set
 | |
| +# CONFIG_BGMAC is not set
 | |
| +# CONFIG_BH1750 is not set
 | |
| +# CONFIG_BH1780 is not set
 | |
| +# CONFIG_BIG_KEYS is not set
 | |
| +# CONFIG_BIG_LITTLE is not set
 | |
| +# CONFIG_BINARY_PRINTF is not set
 | |
| +# CONFIG_BINFMT_AOUT is not set
 | |
| +CONFIG_BINFMT_ELF=y
 | |
| +# CONFIG_BINFMT_ELF_FDPIC is not set
 | |
| +# CONFIG_BINFMT_FLAT is not set
 | |
| +# CONFIG_BINFMT_MISC is not set
 | |
| +CONFIG_BINFMT_SCRIPT=y
 | |
| +CONFIG_BITREVERSE=y
 | |
| +# CONFIG_BLK_CGROUP_IOCOST is not set
 | |
| +# CONFIG_BLK_CGROUP_IOLATENCY is not set
 | |
| +# CONFIG_BLK_CMDLINE_PARSER is not set
 | |
| +# CONFIG_BLK_DEBUG_FS is not set
 | |
| +CONFIG_BLK_DEV=y
 | |
| +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 | |
| +# CONFIG_BLK_DEV_4DRIVES is not set
 | |
| +# CONFIG_BLK_DEV_AEC62XX is not set
 | |
| +# CONFIG_BLK_DEV_ALI14XX is not set
 | |
| +# CONFIG_BLK_DEV_ALI15X3 is not set
 | |
| +# CONFIG_BLK_DEV_AMD74XX is not set
 | |
| +# CONFIG_BLK_DEV_ATIIXP is not set
 | |
| +# CONFIG_BLK_DEV_BSG is not set
 | |
| +# CONFIG_BLK_DEV_BSGLIB is not set
 | |
| +# CONFIG_BLK_DEV_CMD640 is not set
 | |
| +# CONFIG_BLK_DEV_CMD64X is not set
 | |
| +# CONFIG_BLK_DEV_COW_COMMON is not set
 | |
| +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
 | |
| +# CONFIG_BLK_DEV_CS5520 is not set
 | |
| +# CONFIG_BLK_DEV_CS5530 is not set
 | |
| +# CONFIG_BLK_DEV_CS5535 is not set
 | |
| +# CONFIG_BLK_DEV_CS5536 is not set
 | |
| +# CONFIG_BLK_DEV_CY82C693 is not set
 | |
| +# CONFIG_BLK_DEV_DAC960 is not set
 | |
| +# CONFIG_BLK_DEV_DELKIN is not set
 | |
| +# CONFIG_BLK_DEV_DRBD is not set
 | |
| +# CONFIG_BLK_DEV_DTC2278 is not set
 | |
| +# CONFIG_BLK_DEV_FD is not set
 | |
| +# CONFIG_BLK_DEV_GENERIC is not set
 | |
| +# CONFIG_BLK_DEV_HPT366 is not set
 | |
| +# CONFIG_BLK_DEV_HT6560B is not set
 | |
| +# CONFIG_BLK_DEV_IDEACPI is not set
 | |
| +# CONFIG_BLK_DEV_IDECD is not set
 | |
| +# CONFIG_BLK_DEV_IDECS is not set
 | |
| +# CONFIG_BLK_DEV_IDEPCI is not set
 | |
| +# CONFIG_BLK_DEV_IDEPNP is not set
 | |
| +# CONFIG_BLK_DEV_IDETAPE is not set
 | |
| +# CONFIG_BLK_DEV_IDE_AU1XXX is not set
 | |
| +# CONFIG_BLK_DEV_IDE_SATA is not set
 | |
| +CONFIG_BLK_DEV_INITRD=y
 | |
| +# CONFIG_BLK_DEV_INTEGRITY is not set
 | |
| +# CONFIG_BLK_DEV_IO_TRACE is not set
 | |
| +# CONFIG_BLK_DEV_IT8172 is not set
 | |
| +# CONFIG_BLK_DEV_IT8213 is not set
 | |
| +# CONFIG_BLK_DEV_IT821X is not set
 | |
| +# CONFIG_BLK_DEV_JMICRON is not set
 | |
| +# CONFIG_BLK_DEV_LOOP is not set
 | |
| +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8
 | |
| +# CONFIG_BLK_DEV_NBD is not set
 | |
| +# CONFIG_BLK_DEV_NS87415 is not set
 | |
| +# CONFIG_BLK_DEV_NULL_BLK is not set
 | |
| +# CONFIG_BLK_DEV_NVME is not set
 | |
| +# CONFIG_BLK_DEV_OFFBOARD is not set
 | |
| +# CONFIG_BLK_DEV_OPTI621 is not set
 | |
| +# CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set
 | |
| +# CONFIG_BLK_DEV_PDC202XX_NEW is not set
 | |
| +# CONFIG_BLK_DEV_PDC202XX_OLD is not set
 | |
| +# CONFIG_BLK_DEV_PIIX is not set
 | |
| +# CONFIG_BLK_DEV_PLATFORM is not set
 | |
| +# CONFIG_BLK_DEV_PMEM is not set
 | |
| +# CONFIG_BLK_DEV_QD65XX is not set
 | |
| +# CONFIG_BLK_DEV_RAM is not set
 | |
| +# CONFIG_BLK_DEV_RBD is not set
 | |
| +# CONFIG_BLK_DEV_RSXX is not set
 | |
| +# CONFIG_BLK_DEV_RZ1000 is not set
 | |
| +# CONFIG_BLK_DEV_SC1200 is not set
 | |
| +# CONFIG_BLK_DEV_SD is not set
 | |
| +# CONFIG_BLK_DEV_SIIMAGE is not set
 | |
| +# CONFIG_BLK_DEV_SIS5513 is not set
 | |
| +# CONFIG_BLK_DEV_SKD is not set
 | |
| +# CONFIG_BLK_DEV_SL82C105 is not set
 | |
| +# CONFIG_BLK_DEV_SLC90E66 is not set
 | |
| +# CONFIG_BLK_DEV_SR is not set
 | |
| +# CONFIG_BLK_DEV_SVWKS is not set
 | |
| +# CONFIG_BLK_DEV_SX8 is not set
 | |
| +# CONFIG_BLK_DEV_TC86C001 is not set
 | |
| +# CONFIG_BLK_DEV_THROTTLING is not set
 | |
| +# CONFIG_BLK_DEV_TRIFLEX is not set
 | |
| +# CONFIG_BLK_DEV_TRM290 is not set
 | |
| +# CONFIG_BLK_DEV_UMC8672 is not set
 | |
| +# CONFIG_BLK_DEV_UMEM is not set
 | |
| +# CONFIG_BLK_DEV_VIA82CXXX is not set
 | |
| +# CONFIG_BLK_DEV_ZONED is not set
 | |
| +# CONFIG_BLK_INLINE_ENCRYPTION is not set
 | |
| +# CONFIG_BLK_SED_OPAL is not set
 | |
| +# CONFIG_BLK_WBT is not set
 | |
| +CONFIG_BLOCK=y
 | |
| +# CONFIG_BMA180 is not set
 | |
| +# CONFIG_BMA220 is not set
 | |
| +# CONFIG_BMA400 is not set
 | |
| +# CONFIG_BMC150_ACCEL is not set
 | |
| +# CONFIG_BMC150_MAGN is not set
 | |
| +# CONFIG_BMC150_MAGN_I2C is not set
 | |
| +# CONFIG_BMC150_MAGN_SPI is not set
 | |
| +# CONFIG_BME680 is not set
 | |
| +# CONFIG_BMG160 is not set
 | |
| +# CONFIG_BMI160_I2C is not set
 | |
| +# CONFIG_BMI160_SPI is not set
 | |
| +# CONFIG_BMIPS_GENERIC is not set
 | |
| +# CONFIG_BMP280 is not set
 | |
| +# CONFIG_BNA is not set
 | |
| +# CONFIG_BNX2 is not set
 | |
| +# CONFIG_BNX2X is not set
 | |
| +# CONFIG_BNX2X_SRIOV is not set
 | |
| +# CONFIG_BNXT is not set
 | |
| +# CONFIG_BONDING is not set
 | |
| +# CONFIG_BOOKE_WDT is not set
 | |
| +CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3
 | |
| +# CONFIG_BOOTTIME_TRACING is not set
 | |
| +# CONFIG_BOOT_CONFIG is not set
 | |
| +# CONFIG_BOOT_PRINTK_DELAY is not set
 | |
| +CONFIG_BOOT_RAW=y
 | |
| +# CONFIG_BOUNCE is not set
 | |
| +CONFIG_BPF=y
 | |
| +# CONFIG_BPFILTER is not set
 | |
| +CONFIG_BPF_JIT=y
 | |
| +# CONFIG_BPF_JIT_ALWAYS_ON is not set
 | |
| +CONFIG_BPF_JIT_DEFAULT_ON=y
 | |
| +# CONFIG_BPF_PRELOAD is not set
 | |
| +# CONFIG_BPF_STREAM_PARSER is not set
 | |
| +CONFIG_BPF_SYSCALL=y
 | |
| +# CONFIG_BPQETHER is not set
 | |
| +CONFIG_BQL=y
 | |
| +CONFIG_BRANCH_PROFILE_NONE=y
 | |
| +# CONFIG_BRCMFMAC is not set
 | |
| +# CONFIG_BRCMSMAC is not set
 | |
| +# CONFIG_BRCMSTB_GISB_ARB is not set
 | |
| +CONFIG_BRIDGE=y
 | |
| +# CONFIG_BRIDGE_EBT_802_3 is not set
 | |
| +# CONFIG_BRIDGE_EBT_AMONG is not set
 | |
| +# CONFIG_BRIDGE_EBT_ARP is not set
 | |
| +# CONFIG_BRIDGE_EBT_ARPREPLY is not set
 | |
| +# CONFIG_BRIDGE_EBT_BROUTE is not set
 | |
| +# CONFIG_BRIDGE_EBT_DNAT is not set
 | |
| +# CONFIG_BRIDGE_EBT_IP is not set
 | |
| +# CONFIG_BRIDGE_EBT_IP6 is not set
 | |
| +# CONFIG_BRIDGE_EBT_LIMIT is not set
 | |
| +# CONFIG_BRIDGE_EBT_LOG is not set
 | |
| +# CONFIG_BRIDGE_EBT_MARK is not set
 | |
| +# CONFIG_BRIDGE_EBT_MARK_T is not set
 | |
| +# CONFIG_BRIDGE_EBT_NFLOG is not set
 | |
| +# CONFIG_BRIDGE_EBT_PKTTYPE is not set
 | |
| +# CONFIG_BRIDGE_EBT_REDIRECT is not set
 | |
| +# CONFIG_BRIDGE_EBT_SNAT is not set
 | |
| +# CONFIG_BRIDGE_EBT_STP is not set
 | |
| +# CONFIG_BRIDGE_EBT_T_FILTER is not set
 | |
| +# CONFIG_BRIDGE_EBT_T_NAT is not set
 | |
| +# CONFIG_BRIDGE_EBT_VLAN is not set
 | |
| +CONFIG_BRIDGE_IGMP_SNOOPING=y
 | |
| +# CONFIG_BRIDGE_MRP is not set
 | |
| +# CONFIG_BRIDGE_NETFILTER is not set
 | |
| +# CONFIG_BRIDGE_NF_EBTABLES is not set
 | |
| +CONFIG_BRIDGE_VLAN_FILTERING=y
 | |
| +# CONFIG_BROADCOM_PHY is not set
 | |
| +CONFIG_BROKEN_ON_SMP=y
 | |
| +# CONFIG_BSD_DISKLABEL is not set
 | |
| +# CONFIG_BSD_PROCESS_ACCT is not set
 | |
| +# CONFIG_BSD_PROCESS_ACCT_V3 is not set
 | |
| +# CONFIG_BT is not set
 | |
| +# CONFIG_BTRFS_ASSERT is not set
 | |
| +# CONFIG_BTRFS_DEBUG is not set
 | |
| +# CONFIG_BTRFS_FS is not set
 | |
| +# CONFIG_BTRFS_FS_POSIX_ACL is not set
 | |
| +# CONFIG_BTRFS_FS_REF_VERIFY is not set
 | |
| +# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
 | |
| +# CONFIG_BT_ATH3K is not set
 | |
| +# CONFIG_BT_BNEP is not set
 | |
| +CONFIG_BT_BNEP_MC_FILTER=y
 | |
| +CONFIG_BT_BNEP_PROTO_FILTER=y
 | |
| +# CONFIG_BT_BREDR is not set
 | |
| +# CONFIG_BT_CMTP is not set
 | |
| +# CONFIG_BT_FEATURE_DEBUG is not set
 | |
| +# CONFIG_BT_HCIBCM203X is not set
 | |
| +# CONFIG_BT_HCIBFUSB is not set
 | |
| +# CONFIG_BT_HCIBLUECARD is not set
 | |
| +# CONFIG_BT_HCIBPA10X is not set
 | |
| +# CONFIG_BT_HCIBT3C is not set
 | |
| +# CONFIG_BT_HCIBTSDIO is not set
 | |
| +# CONFIG_BT_HCIBTUSB is not set
 | |
| +# CONFIG_BT_HCIBTUSB_AUTOSUSPEND is not set
 | |
| +# CONFIG_BT_HCIBTUSB_MTK is not set
 | |
| +# CONFIG_BT_HCIBTUSB_RTL is not set
 | |
| +# CONFIG_BT_HCIDTL1 is not set
 | |
| +# CONFIG_BT_HCIUART is not set
 | |
| +# CONFIG_BT_HCIUART_3WIRE is not set
 | |
| +# CONFIG_BT_HCIUART_AG6XX is not set
 | |
| +# CONFIG_BT_HCIUART_ATH3K is not set
 | |
| +CONFIG_BT_HCIUART_BCSP=y
 | |
| +CONFIG_BT_HCIUART_H4=y
 | |
| +# CONFIG_BT_HCIUART_LL is not set
 | |
| +# CONFIG_BT_HCIUART_MRVL is not set
 | |
| +# CONFIG_BT_HCIUART_QCA is not set
 | |
| +# CONFIG_BT_HCIUART_RTL is not set
 | |
| +# CONFIG_BT_HCIVHCI is not set
 | |
| +# CONFIG_BT_HIDP is not set
 | |
| +# CONFIG_BT_HS is not set
 | |
| +# CONFIG_BT_LE is not set
 | |
| +# CONFIG_BT_LEDS is not set
 | |
| +# CONFIG_BT_MRVL is not set
 | |
| +# CONFIG_BT_MSFTEXT is not set
 | |
| +# CONFIG_BT_MTKSDIO is not set
 | |
| +# CONFIG_BT_MTKUART is not set
 | |
| +# CONFIG_BT_RFCOMM is not set
 | |
| +CONFIG_BT_RFCOMM_TTY=y
 | |
| +# CONFIG_BT_SELFTEST is not set
 | |
| +CONFIG_BUG=y
 | |
| +# CONFIG_BUG_ON_DATA_CORRUPTION is not set
 | |
| +CONFIG_BUILDTIME_EXTABLE_SORT=y
 | |
| +CONFIG_BUILDTIME_TABLE_SORT=y
 | |
| +# CONFIG_BUILD_BIN2C is not set
 | |
| +CONFIG_BUILD_SALT=""
 | |
| +# CONFIG_C2PORT is not set
 | |
| +CONFIG_CACHE_L2X0_PMU=y
 | |
| +# CONFIG_CADENCE_WATCHDOG is not set
 | |
| +# CONFIG_CAIF is not set
 | |
| +# CONFIG_CAN is not set
 | |
| +# CONFIG_CAN_BCM is not set
 | |
| +# CONFIG_CAN_DEBUG_DEVICES is not set
 | |
| +# CONFIG_CAN_DEV is not set
 | |
| +# CONFIG_CAN_GS_USB is not set
 | |
| +# CONFIG_CAN_GW is not set
 | |
| +# CONFIG_CAN_HI311X is not set
 | |
| +# CONFIG_CAN_IFI_CANFD is not set
 | |
| +# CONFIG_CAN_ISOTP is not set
 | |
| +# CONFIG_CAN_J1939 is not set
 | |
| +# CONFIG_CAN_KVASER_PCIEFD is not set
 | |
| +# CONFIG_CAN_MCBA_USB is not set
 | |
| +# CONFIG_CAN_MCP251XFD is not set
 | |
| +# CONFIG_CAN_M_CAN is not set
 | |
| +# CONFIG_CAN_PEAK_PCIEFD is not set
 | |
| +# CONFIG_CAN_RAW is not set
 | |
| +# CONFIG_CAN_RCAR is not set
 | |
| +# CONFIG_CAN_RCAR_CANFD is not set
 | |
| +# CONFIG_CAN_SLCAN is not set
 | |
| +# CONFIG_CAN_SUN4I is not set
 | |
| +# CONFIG_CAN_UCAN is not set
 | |
| +# CONFIG_CAN_VCAN is not set
 | |
| +# CONFIG_CAN_VXCAN is not set
 | |
| +# CONFIG_CAPI_AVM is not set
 | |
| +# CONFIG_CAPI_EICON is not set
 | |
| +# CONFIG_CAPI_TRACE is not set
 | |
| +CONFIG_CARDBUS=y
 | |
| +# CONFIG_CARDMAN_4000 is not set
 | |
| +# CONFIG_CARDMAN_4040 is not set
 | |
| +# CONFIG_CARL9170 is not set
 | |
| +# CONFIG_CASSINI is not set
 | |
| +# CONFIG_CAVIUM_CPT is not set
 | |
| +# CONFIG_CAVIUM_ERRATUM_22375 is not set
 | |
| +# CONFIG_CAVIUM_ERRATUM_23144 is not set
 | |
| +# CONFIG_CAVIUM_ERRATUM_23154 is not set
 | |
| +# CONFIG_CAVIUM_ERRATUM_27456 is not set
 | |
| +# CONFIG_CAVIUM_ERRATUM_30115 is not set
 | |
| +# CONFIG_CAVIUM_OCTEON_SOC is not set
 | |
| +# CONFIG_CAVIUM_PTP is not set
 | |
| +# CONFIG_CB710_CORE is not set
 | |
| +# CONFIG_CC10001_ADC is not set
 | |
| +# CONFIG_CCS811 is not set
 | |
| +CONFIG_CC_CAN_LINK=y
 | |
| +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
 | |
| +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 | |
| +# CONFIG_CDROM_PKTCDVD is not set
 | |
| +# CONFIG_CEPH_FS is not set
 | |
| +# CONFIG_CEPH_LIB is not set
 | |
| +# CONFIG_CFG80211 is not set
 | |
| +# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
 | |
| +# CONFIG_CGROUPS is not set
 | |
| +# CONFIG_CHARGER_ADP5061 is not set
 | |
| +# CONFIG_CHARGER_BD99954 is not set
 | |
| +# CONFIG_CHARGER_BQ2415X is not set
 | |
| +# CONFIG_CHARGER_BQ24190 is not set
 | |
| +# CONFIG_CHARGER_BQ24257 is not set
 | |
| +# CONFIG_CHARGER_BQ24735 is not set
 | |
| +# CONFIG_CHARGER_BQ2515X is not set
 | |
| +# CONFIG_CHARGER_BQ25890 is not set
 | |
| +# CONFIG_CHARGER_BQ25980 is not set
 | |
| +# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
 | |
| +# CONFIG_CHARGER_GPIO is not set
 | |
| +# CONFIG_CHARGER_ISP1704 is not set
 | |
| +# CONFIG_CHARGER_LP8727 is not set
 | |
| +# CONFIG_CHARGER_LT3651 is not set
 | |
| +# CONFIG_CHARGER_LTC3651 is not set
 | |
| +# CONFIG_CHARGER_MANAGER is not set
 | |
| +# CONFIG_CHARGER_MAX8903 is not set
 | |
| +# CONFIG_CHARGER_RT9455 is not set
 | |
| +# CONFIG_CHARGER_SBS is not set
 | |
| +# CONFIG_CHARGER_SMB347 is not set
 | |
| +# CONFIG_CHARGER_TWL4030 is not set
 | |
| +# CONFIG_CHARGER_UCS1002 is not set
 | |
| +# CONFIG_CHASH_SELFTEST is not set
 | |
| +# CONFIG_CHASH_STATS is not set
 | |
| +# CONFIG_CHECKPOINT_RESTORE is not set
 | |
| +# CONFIG_CHELSIO_T1 is not set
 | |
| +# CONFIG_CHELSIO_T3 is not set
 | |
| +# CONFIG_CHELSIO_T4 is not set
 | |
| +# CONFIG_CHELSIO_T4VF is not set
 | |
| +# CONFIG_CHROME_PLATFORMS is not set
 | |
| +# CONFIG_CHR_DEV_OSST is not set
 | |
| +# CONFIG_CHR_DEV_SCH is not set
 | |
| +# CONFIG_CHR_DEV_SG is not set
 | |
| +# CONFIG_CHR_DEV_ST is not set
 | |
| +# CONFIG_CICADA_PHY is not set
 | |
| +# CONFIG_CIFS is not set
 | |
| +# CONFIG_CIFS_ACL is not set
 | |
| +CONFIG_CIFS_ALLOW_INSECURE_LEGACY=y
 | |
| +# CONFIG_CIFS_DEBUG is not set
 | |
| +# CONFIG_CIFS_DEBUG2 is not set
 | |
| +# CONFIG_CIFS_FSCACHE is not set
 | |
| +# CONFIG_CIFS_NFSD_EXPORT is not set
 | |
| +CONFIG_CIFS_POSIX=y
 | |
| +# CONFIG_CIFS_SMB2 is not set
 | |
| +# CONFIG_CIFS_STATS is not set
 | |
| +# CONFIG_CIFS_STATS2 is not set
 | |
| +# CONFIG_CIFS_WEAK_PW_HASH is not set
 | |
| +CONFIG_CIFS_XATTR=y
 | |
| +# CONFIG_CIO_DAC is not set
 | |
| +CONFIG_CLANG_VERSION=0
 | |
| +# CONFIG_CLEANCACHE is not set
 | |
| +# CONFIG_CLKSRC_VERSATILE is not set
 | |
| +# CONFIG_CLK_HSDK is not set
 | |
| +# CONFIG_CLK_QORIQ is not set
 | |
| +# CONFIG_CLOCK_THERMAL is not set
 | |
| +CONFIG_CLS_U32_MARK=y
 | |
| +# CONFIG_CLS_U32_PERF is not set
 | |
| +# CONFIG_CM32181 is not set
 | |
| +# CONFIG_CM3232 is not set
 | |
| +# CONFIG_CM3323 is not set
 | |
| +# CONFIG_CM3605 is not set
 | |
| +# CONFIG_CM36651 is not set
 | |
| +# CONFIG_CMA is not set
 | |
| +CONFIG_CMDLINE=""
 | |
| +# CONFIG_CMDLINE_BOOL is not set
 | |
| +# CONFIG_CMDLINE_EXTEND is not set
 | |
| +# CONFIG_CMDLINE_FORCE is not set
 | |
| +# CONFIG_CMDLINE_FROM_BOOTLOADER is not set
 | |
| +# CONFIG_CMDLINE_PARTITION is not set
 | |
| +# CONFIG_CNIC is not set
 | |
| +# CONFIG_CODA_FS is not set
 | |
| +# CONFIG_CODE_PATCHING_SELFTEST is not set
 | |
| +# CONFIG_COMEDI is not set
 | |
| +# CONFIG_COMMON_CLK_CDCE706 is not set
 | |
| +# CONFIG_COMMON_CLK_CDCE925 is not set
 | |
| +# CONFIG_COMMON_CLK_CS2000_CP is not set
 | |
| +# CONFIG_COMMON_CLK_FIXED_MMIO is not set
 | |
| +# CONFIG_COMMON_CLK_IPROC is not set
 | |
| +# CONFIG_COMMON_CLK_MAX9485 is not set
 | |
| +# CONFIG_COMMON_CLK_MT6765 is not set
 | |
| +# CONFIG_COMMON_CLK_MT8167 is not set
 | |
| +# CONFIG_COMMON_CLK_MT8167_AUDSYS is not set
 | |
| +# CONFIG_COMMON_CLK_MT8167_IMGSYS is not set
 | |
| +# CONFIG_COMMON_CLK_MT8167_MFGCFG is not set
 | |
| +# CONFIG_COMMON_CLK_MT8167_MMSYS is not set
 | |
| +# CONFIG_COMMON_CLK_MT8167_VDECSYS is not set
 | |
| +# CONFIG_COMMON_CLK_NXP is not set
 | |
| +# CONFIG_COMMON_CLK_PIC32 is not set
 | |
| +# CONFIG_COMMON_CLK_PWM is not set
 | |
| +# CONFIG_COMMON_CLK_PXA is not set
 | |
| +# CONFIG_COMMON_CLK_QCOM is not set
 | |
| +# CONFIG_COMMON_CLK_SI514 is not set
 | |
| +# CONFIG_COMMON_CLK_SI5341 is not set
 | |
| +# CONFIG_COMMON_CLK_SI5351 is not set
 | |
| +# CONFIG_COMMON_CLK_SI544 is not set
 | |
| +# CONFIG_COMMON_CLK_SI570 is not set
 | |
| +# CONFIG_COMMON_CLK_VC5 is not set
 | |
| +# CONFIG_COMMON_CLK_XGENE is not set
 | |
| +# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set
 | |
| +CONFIG_COMPACTION=y
 | |
| +# CONFIG_COMPAL_LAPTOP is not set
 | |
| +# CONFIG_COMPAT is not set
 | |
| +# CONFIG_COMPAT_BRK is not set
 | |
| +# CONFIG_COMPILE_TEST is not set
 | |
| +# CONFIG_CONFIGFS_FS is not set
 | |
| +# CONFIG_CONNECTOR is not set
 | |
| +CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
 | |
| +CONFIG_CONSOLE_LOGLEVEL_QUIET=4
 | |
| +CONFIG_CONSTRUCTORS=y
 | |
| +# CONFIG_CONTEXT_SWITCH_TRACER is not set
 | |
| +# CONFIG_COPS is not set
 | |
| +# CONFIG_CORDIC is not set
 | |
| +# CONFIG_COREDUMP is not set
 | |
| +# CONFIG_CORESIGHT is not set
 | |
| +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 | |
| +# CONFIG_CORTINA_PHY is not set
 | |
| +# CONFIG_COUNTER is not set
 | |
| +# CONFIG_CPA_DEBUG is not set
 | |
| +# CONFIG_CPU_BIG_ENDIAN is not set
 | |
| +# CONFIG_CPU_BPREDICT_DISABLE is not set
 | |
| +# CONFIG_CPU_DCACHE_DISABLE is not set
 | |
| +# CONFIG_CPU_FREQ is not set
 | |
| +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
 | |
| +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
 | |
| +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
 | |
| +# CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL is not set
 | |
| +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
 | |
| +# CONFIG_CPU_FREQ_GOV_SCHEDUTIL is not set
 | |
| +# CONFIG_CPU_FREQ_STAT_DETAILS is not set
 | |
| +# CONFIG_CPU_FREQ_THERMAL is not set
 | |
| +# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
 | |
| +# CONFIG_CPU_ICACHE_DISABLE is not set
 | |
| +# CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set
 | |
| +# CONFIG_CPU_IDLE is not set
 | |
| +# CONFIG_CPU_IDLE_GOV_LADDER is not set
 | |
| +# CONFIG_CPU_IDLE_GOV_MENU is not set
 | |
| +# CONFIG_CPU_IDLE_GOV_TEO is not set
 | |
| +# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
 | |
| +# CONFIG_CPU_ISOLATION is not set
 | |
| +CONFIG_CPU_LITTLE_ENDIAN=y
 | |
| +# CONFIG_CPU_NO_EFFICIENT_FFS is not set
 | |
| +CONFIG_CPU_SW_DOMAIN_PAN=y
 | |
| +# CONFIG_CRAMFS is not set
 | |
| +CONFIG_CRAMFS_BLOCKDEV=y
 | |
| +# CONFIG_CRAMFS_MTD is not set
 | |
| +# CONFIG_CRASH_DUMP is not set
 | |
| +# CONFIG_CRC16 is not set
 | |
| +CONFIG_CRC32=y
 | |
| +# CONFIG_CRC32_BIT is not set
 | |
| +CONFIG_CRC32_SARWATE=y
 | |
| +# CONFIG_CRC32_SELFTEST is not set
 | |
| +# CONFIG_CRC32_SLICEBY4 is not set
 | |
| +# CONFIG_CRC32_SLICEBY8 is not set
 | |
| +# CONFIG_CRC4 is not set
 | |
| +# CONFIG_CRC64 is not set
 | |
| +# CONFIG_CRC7 is not set
 | |
| +# CONFIG_CRC8 is not set
 | |
| +# CONFIG_CRC_CCITT is not set
 | |
| +# CONFIG_CRC_ITU_T is not set
 | |
| +# CONFIG_CRC_T10DIF is not set
 | |
| +CONFIG_CROSS_COMPILE=""
 | |
| +# CONFIG_CROSS_MEMORY_ATTACH is not set
 | |
| +CONFIG_CRYPTO=y
 | |
| +# CONFIG_CRYPTO_842 is not set
 | |
| +# CONFIG_CRYPTO_ADIANTUM is not set
 | |
| +# CONFIG_CRYPTO_AEAD is not set
 | |
| +# CONFIG_CRYPTO_AEGIS128 is not set
 | |
| +# CONFIG_CRYPTO_AEGIS128L is not set
 | |
| +# CONFIG_CRYPTO_AEGIS128L_AESNI_SSE2 is not set
 | |
| +# CONFIG_CRYPTO_AEGIS128_AESNI_SSE2 is not set
 | |
| +# CONFIG_CRYPTO_AEGIS256 is not set
 | |
| +# CONFIG_CRYPTO_AEGIS256_AESNI_SSE2 is not set
 | |
| +CONFIG_CRYPTO_AES=y
 | |
| +# CONFIG_CRYPTO_AES_586 is not set
 | |
| +# CONFIG_CRYPTO_AES_ARM is not set
 | |
| +# CONFIG_CRYPTO_AES_ARM_BS is not set
 | |
| +# CONFIG_CRYPTO_AES_ARM_CE is not set
 | |
| +# CONFIG_CRYPTO_AES_NI_INTEL is not set
 | |
| +# CONFIG_CRYPTO_AES_TI is not set
 | |
| +CONFIG_CRYPTO_ALGAPI=y
 | |
| +CONFIG_CRYPTO_ALGAPI2=y
 | |
| +# CONFIG_CRYPTO_ANSI_CPRNG is not set
 | |
| +# CONFIG_CRYPTO_ANUBIS is not set
 | |
| +# CONFIG_CRYPTO_ARC4 is not set
 | |
| +# CONFIG_CRYPTO_AUTHENC is not set
 | |
| +# CONFIG_CRYPTO_BLAKE2B is not set
 | |
| +# CONFIG_CRYPTO_BLAKE2S is not set
 | |
| +# CONFIG_CRYPTO_BLAKE2S_X86 is not set
 | |
| +# CONFIG_CRYPTO_BLOWFISH is not set
 | |
| +# CONFIG_CRYPTO_CAMELLIA is not set
 | |
| +# CONFIG_CRYPTO_CAST5 is not set
 | |
| +# CONFIG_CRYPTO_CAST6 is not set
 | |
| +# CONFIG_CRYPTO_CBC is not set
 | |
| +# CONFIG_CRYPTO_CCM is not set
 | |
| +# CONFIG_CRYPTO_CFB is not set
 | |
| +# CONFIG_CRYPTO_CHACHA20 is not set
 | |
| +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
 | |
| +# CONFIG_CRYPTO_CHACHA20_NEON is not set
 | |
| +# CONFIG_CRYPTO_CHACHA20_X86_64 is not set
 | |
| +# CONFIG_CRYPTO_CHACHA_MIPS is not set
 | |
| +# CONFIG_CRYPTO_CMAC is not set
 | |
| +# CONFIG_CRYPTO_CRC32 is not set
 | |
| +# CONFIG_CRYPTO_CRC32C is not set
 | |
| +# CONFIG_CRYPTO_CRC32C_INTEL is not set
 | |
| +# CONFIG_CRYPTO_CRC32_ARM_CE is not set
 | |
| +# CONFIG_CRYPTO_CRCT10DIF is not set
 | |
| +# CONFIG_CRYPTO_CRYPTD is not set
 | |
| +# CONFIG_CRYPTO_CTR is not set
 | |
| +# CONFIG_CRYPTO_CTS is not set
 | |
| +# CONFIG_CRYPTO_CURVE25519 is not set
 | |
| +# CONFIG_CRYPTO_CURVE25519_NEON is not set
 | |
| +# CONFIG_CRYPTO_CURVE25519_X86 is not set
 | |
| +# CONFIG_CRYPTO_DEFLATE is not set
 | |
| +# CONFIG_CRYPTO_DES is not set
 | |
| +# CONFIG_CRYPTO_DEV_AMLOGIC_GXL is not set
 | |
| +# CONFIG_CRYPTO_DEV_ATMEL_AES is not set
 | |
| +# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set
 | |
| +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
 | |
| +# CONFIG_CRYPTO_DEV_ATMEL_SHA is not set
 | |
| +# CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
 | |
| +# CONFIG_CRYPTO_DEV_ATMEL_TDES is not set
 | |
| +# CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set
 | |
| +# CONFIG_CRYPTO_DEV_CCP is not set
 | |
| +# CONFIG_CRYPTO_DEV_CCP_DEBUGFS is not set
 | |
| +# CONFIG_CRYPTO_DEV_CCREE is not set
 | |
| +# CONFIG_CRYPTO_DEV_FSL_CAAM is not set
 | |
| +# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set
 | |
| +# CONFIG_CRYPTO_DEV_HIFN_795X is not set
 | |
| +# CONFIG_CRYPTO_DEV_HISI_SEC is not set
 | |
| +# CONFIG_CRYPTO_DEV_HISI_ZIP is not set
 | |
| +# CONFIG_CRYPTO_DEV_IMGTEC_HASH is not set
 | |
| +# CONFIG_CRYPTO_DEV_MARVELL_CESA is not set
 | |
| +# CONFIG_CRYPTO_DEV_MV_CESA is not set
 | |
| +# CONFIG_CRYPTO_DEV_MXC_SCC is not set
 | |
| +# CONFIG_CRYPTO_DEV_MXS_DCP is not set
 | |
| +# CONFIG_CRYPTO_DEV_NITROX_CNN55XX is not set
 | |
| +# CONFIG_CRYPTO_DEV_QAT_C3XXX is not set
 | |
| +# CONFIG_CRYPTO_DEV_QAT_C3XXXVF is not set
 | |
| +# CONFIG_CRYPTO_DEV_QAT_C62X is not set
 | |
| +# CONFIG_CRYPTO_DEV_QAT_C62XVF is not set
 | |
| +# CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set
 | |
| +# CONFIG_CRYPTO_DEV_QAT_DH895xCCVF is not set
 | |
| +# CONFIG_CRYPTO_DEV_QCE is not set
 | |
| +# CONFIG_CRYPTO_DEV_S5P is not set
 | |
| +# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
 | |
| +# CONFIG_CRYPTO_DEV_SAHARA is not set
 | |
| +# CONFIG_CRYPTO_DEV_SP_PSP is not set
 | |
| +# CONFIG_CRYPTO_DEV_TALITOS is not set
 | |
| +# CONFIG_CRYPTO_DEV_VIRTIO is not set
 | |
| +# CONFIG_CRYPTO_DH is not set
 | |
| +# CONFIG_CRYPTO_DRBG_CTR is not set
 | |
| +# CONFIG_CRYPTO_DRBG_HASH is not set
 | |
| +# CONFIG_CRYPTO_DRBG_MENU is not set
 | |
| +# CONFIG_CRYPTO_ECB is not set
 | |
| +# CONFIG_CRYPTO_ECDH is not set
 | |
| +# CONFIG_CRYPTO_ECHAINIV is not set
 | |
| +# CONFIG_CRYPTO_ECRDSA is not set
 | |
| +# CONFIG_CRYPTO_ESSIV is not set
 | |
| +# CONFIG_CRYPTO_FCRYPT is not set
 | |
| +# CONFIG_CRYPTO_FIPS is not set
 | |
| +# CONFIG_CRYPTO_GCM is not set
 | |
| +# CONFIG_CRYPTO_GF128MUL is not set
 | |
| +# CONFIG_CRYPTO_GHASH is not set
 | |
| +# CONFIG_CRYPTO_GHASH_ARM_CE is not set
 | |
| +# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
 | |
| +# CONFIG_CRYPTO_HASH is not set
 | |
| +# CONFIG_CRYPTO_HMAC is not set
 | |
| +# CONFIG_CRYPTO_HW is not set
 | |
| +# CONFIG_CRYPTO_JITTERENTROPY is not set
 | |
| +# CONFIG_CRYPTO_KEYWRAP is not set
 | |
| +# CONFIG_CRYPTO_KHAZAD is not set
 | |
| +CONFIG_CRYPTO_LIB_AES=y
 | |
| +CONFIG_CRYPTO_LIB_ARC4=y
 | |
| +# CONFIG_CRYPTO_LIB_BLAKE2S is not set
 | |
| +# CONFIG_CRYPTO_LIB_CHACHA is not set
 | |
| +# CONFIG_CRYPTO_LIB_CHACHA20POLY1305 is not set
 | |
| +# CONFIG_CRYPTO_LIB_CURVE25519 is not set
 | |
| +# CONFIG_CRYPTO_LIB_POLY1305 is not set
 | |
| +CONFIG_CRYPTO_LIB_POLY1305_RSIZE=9
 | |
| +# CONFIG_CRYPTO_LRW is not set
 | |
| +# CONFIG_CRYPTO_LZ4 is not set
 | |
| +# CONFIG_CRYPTO_LZ4HC is not set
 | |
| +# CONFIG_CRYPTO_LZO is not set
 | |
| +# CONFIG_CRYPTO_MANAGER is not set
 | |
| +# CONFIG_CRYPTO_MANAGER2 is not set
 | |
| +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
 | |
| +# CONFIG_CRYPTO_MCRYPTD is not set
 | |
| +# CONFIG_CRYPTO_MD4 is not set
 | |
| +# CONFIG_CRYPTO_MD5 is not set
 | |
| +# CONFIG_CRYPTO_MICHAEL_MIC is not set
 | |
| +# CONFIG_CRYPTO_MORUS1280 is not set
 | |
| +# CONFIG_CRYPTO_MORUS1280_AVX2 is not set
 | |
| +# CONFIG_CRYPTO_MORUS1280_SSE2 is not set
 | |
| +# CONFIG_CRYPTO_MORUS640 is not set
 | |
| +# CONFIG_CRYPTO_MORUS640_SSE2 is not set
 | |
| +# CONFIG_CRYPTO_NHPOLY1305_NEON is not set
 | |
| +# CONFIG_CRYPTO_NULL is not set
 | |
| +# CONFIG_CRYPTO_OFB is not set
 | |
| +# CONFIG_CRYPTO_PCBC is not set
 | |
| +# CONFIG_CRYPTO_PCOMP is not set
 | |
| +# CONFIG_CRYPTO_PCOMP2 is not set
 | |
| +CONFIG_CRYPTO_PCRYPT=y
 | |
| +# CONFIG_CRYPTO_POLY1305 is not set
 | |
| +# CONFIG_CRYPTO_POLY1305_ARM is not set
 | |
| +# CONFIG_CRYPTO_POLY1305_MIPS is not set
 | |
| +# CONFIG_CRYPTO_POLY1305_NEON is not set
 | |
| +# CONFIG_CRYPTO_POLY1305_X86_64 is not set
 | |
| +# CONFIG_CRYPTO_RMD128 is not set
 | |
| +# CONFIG_CRYPTO_RMD160 is not set
 | |
| +# CONFIG_CRYPTO_RMD256 is not set
 | |
| +# CONFIG_CRYPTO_RMD320 is not set
 | |
| +# CONFIG_CRYPTO_RNG is not set
 | |
| +# CONFIG_CRYPTO_RSA is not set
 | |
| +# CONFIG_CRYPTO_SALSA20 is not set
 | |
| +# CONFIG_CRYPTO_SALSA20_586 is not set
 | |
| +# CONFIG_CRYPTO_SEED is not set
 | |
| +# CONFIG_CRYPTO_SEQIV is not set
 | |
| +# CONFIG_CRYPTO_SERPENT is not set
 | |
| +# CONFIG_CRYPTO_SHA1 is not set
 | |
| +# CONFIG_CRYPTO_SHA1_ARM is not set
 | |
| +# CONFIG_CRYPTO_SHA1_ARM_CE is not set
 | |
| +# CONFIG_CRYPTO_SHA1_ARM_NEON is not set
 | |
| +# CONFIG_CRYPTO_SHA256 is not set
 | |
| +# CONFIG_CRYPTO_SHA256_ARM is not set
 | |
| +# CONFIG_CRYPTO_SHA2_ARM_CE is not set
 | |
| +# CONFIG_CRYPTO_SHA3 is not set
 | |
| +# CONFIG_CRYPTO_SHA3_ARM64 is not set
 | |
| +# CONFIG_CRYPTO_SHA512 is not set
 | |
| +# CONFIG_CRYPTO_SHA512_ARM is not set
 | |
| +# CONFIG_CRYPTO_SHA512_ARM64_CE is not set
 | |
| +# CONFIG_CRYPTO_SIMD is not set
 | |
| +CONFIG_CRYPTO_SKCIPHER=y
 | |
| +CONFIG_CRYPTO_SKCIPHER2=y
 | |
| +# CONFIG_CRYPTO_SM2 is not set
 | |
| +# CONFIG_CRYPTO_SM3 is not set
 | |
| +# CONFIG_CRYPTO_SM3_ARM64_CE is not set
 | |
| +# CONFIG_CRYPTO_SM4 is not set
 | |
| +# CONFIG_CRYPTO_SM4_ARM64_CE is not set
 | |
| +# CONFIG_CRYPTO_SPECK is not set
 | |
| +# CONFIG_CRYPTO_STATS is not set
 | |
| +# CONFIG_CRYPTO_STREEBOG is not set
 | |
| +# CONFIG_CRYPTO_TEA is not set
 | |
| +# CONFIG_CRYPTO_TEST is not set
 | |
| +# CONFIG_CRYPTO_TGR192 is not set
 | |
| +# CONFIG_CRYPTO_TWOFISH is not set
 | |
| +# CONFIG_CRYPTO_TWOFISH_586 is not set
 | |
| +# CONFIG_CRYPTO_TWOFISH_COMMON is not set
 | |
| +# CONFIG_CRYPTO_USER is not set
 | |
| +# CONFIG_CRYPTO_USER_API_AEAD is not set
 | |
| +# CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE is not set
 | |
| +# CONFIG_CRYPTO_USER_API_HASH is not set
 | |
| +# CONFIG_CRYPTO_USER_API_RNG is not set
 | |
| +# CONFIG_CRYPTO_USER_API_RNG_CAVP is not set
 | |
| +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
 | |
| +# CONFIG_CRYPTO_VMAC is not set
 | |
| +# CONFIG_CRYPTO_WP512 is not set
 | |
| +# CONFIG_CRYPTO_XCBC is not set
 | |
| +# CONFIG_CRYPTO_XTS is not set
 | |
| +# CONFIG_CRYPTO_XXHASH is not set
 | |
| +# CONFIG_CRYPTO_ZLIB is not set
 | |
| +# CONFIG_CRYPTO_ZSTD is not set
 | |
| +# CONFIG_CS5535_MFGPT is not set
 | |
| +# CONFIG_CS89x0 is not set
 | |
| +# CONFIG_CSD_LOCK_WAIT_DEBUG is not set
 | |
| +# CONFIG_CUSE is not set
 | |
| +# CONFIG_CW1200 is not set
 | |
| +# CONFIG_CXD2880_SPI_DRV is not set
 | |
| +# CONFIG_CXL_AFU_DRIVER_OPS is not set
 | |
| +# CONFIG_CXL_BASE is not set
 | |
| +# CONFIG_CXL_EEH is not set
 | |
| +# CONFIG_CXL_KERNEL_API is not set
 | |
| +# CONFIG_CXL_LIB is not set
 | |
| +# CONFIG_CYPRESS_FIRMWARE is not set
 | |
| +# CONFIG_DA280 is not set
 | |
| +# CONFIG_DA311 is not set
 | |
| +# CONFIG_DAVICOM_PHY is not set
 | |
| +# CONFIG_DAX is not set
 | |
| +# CONFIG_DCB is not set
 | |
| +# CONFIG_DDR is not set
 | |
| +# CONFIG_DEBUG_ALIGN_RODATA is not set
 | |
| +# CONFIG_DEBUG_ATOMIC_SLEEP is not set
 | |
| +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 | |
| +# CONFIG_DEBUG_BUGVERBOSE is not set
 | |
| +# CONFIG_DEBUG_CREDENTIALS is not set
 | |
| +# CONFIG_DEBUG_DEVRES is not set
 | |
| +# CONFIG_DEBUG_DRIVER is not set
 | |
| +# CONFIG_DEBUG_EFI is not set
 | |
| +# CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B is not set
 | |
| +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
 | |
| +CONFIG_DEBUG_FS=y
 | |
| +CONFIG_DEBUG_FS_ALLOW_ALL=y
 | |
| +# CONFIG_DEBUG_FS_ALLOW_NONE is not set
 | |
| +# CONFIG_DEBUG_FS_DISALLOW_MOUNT is not set
 | |
| +# CONFIG_DEBUG_GPIO is not set
 | |
| +# CONFIG_DEBUG_HIGHMEM is not set
 | |
| +# CONFIG_DEBUG_ICEDCC is not set
 | |
| +# CONFIG_DEBUG_INFO is not set
 | |
| +# CONFIG_DEBUG_INFO_BTF is not set
 | |
| +# CONFIG_DEBUG_INFO_COMPRESSED is not set
 | |
| +# CONFIG_DEBUG_INFO_DWARF4 is not set
 | |
| +CONFIG_DEBUG_INFO_REDUCED=y
 | |
| +# CONFIG_DEBUG_INFO_SPLIT is not set
 | |
| +CONFIG_DEBUG_KERNEL=y
 | |
| +# CONFIG_DEBUG_KMEMLEAK is not set
 | |
| +# CONFIG_DEBUG_KOBJECT is not set
 | |
| +# CONFIG_DEBUG_KOBJECT_RELEASE is not set
 | |
| +# CONFIG_DEBUG_LIST is not set
 | |
| +# CONFIG_DEBUG_LL is not set
 | |
| +# CONFIG_DEBUG_LL_UART_8250 is not set
 | |
| +# CONFIG_DEBUG_LL_UART_PL01X is not set
 | |
| +# CONFIG_DEBUG_LOCKDEP is not set
 | |
| +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 | |
| +# CONFIG_DEBUG_LOCK_ALLOC is not set
 | |
| +# CONFIG_DEBUG_MEMORY_INIT is not set
 | |
| +# CONFIG_DEBUG_MISC is not set
 | |
| +# CONFIG_DEBUG_MUTEXES is not set
 | |
| +# CONFIG_DEBUG_NOTIFIERS is not set
 | |
| +# CONFIG_DEBUG_NX_TEST is not set
 | |
| +# CONFIG_DEBUG_OBJECTS is not set
 | |
| +# CONFIG_DEBUG_PAGEALLOC is not set
 | |
| +# CONFIG_DEBUG_PAGE_REF is not set
 | |
| +# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
 | |
| +# CONFIG_DEBUG_PER_CPU_MAPS is not set
 | |
| +# CONFIG_DEBUG_PINCTRL is not set
 | |
| +# CONFIG_DEBUG_PI_LIST is not set
 | |
| +# CONFIG_DEBUG_PLIST is not set
 | |
| +# CONFIG_DEBUG_PREEMPT is not set
 | |
| +# CONFIG_DEBUG_RODATA_TEST is not set
 | |
| +# CONFIG_DEBUG_RSEQ is not set
 | |
| +# CONFIG_DEBUG_RT_MUTEXES is not set
 | |
| +# CONFIG_DEBUG_RWSEMS is not set
 | |
| +# CONFIG_DEBUG_SECTION_MISMATCH is not set
 | |
| +# CONFIG_DEBUG_SEMIHOSTING is not set
 | |
| +# CONFIG_DEBUG_SG is not set
 | |
| +# CONFIG_DEBUG_SHIRQ is not set
 | |
| +# CONFIG_DEBUG_SLAB is not set
 | |
| +# CONFIG_DEBUG_SPINLOCK is not set
 | |
| +# CONFIG_DEBUG_STACKOVERFLOW is not set
 | |
| +# CONFIG_DEBUG_STACK_USAGE is not set
 | |
| +# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
 | |
| +# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
 | |
| +# CONFIG_DEBUG_TIMEKEEPING is not set
 | |
| +# CONFIG_DEBUG_UART_8250_PALMCHIP is not set
 | |
| +# CONFIG_DEBUG_UART_8250_WORD is not set
 | |
| +# CONFIG_DEBUG_UART_BCM63XX is not set
 | |
| +# CONFIG_DEBUG_UART_FLOW_CONTROL is not set
 | |
| +# CONFIG_DEBUG_USER is not set
 | |
| +# CONFIG_DEBUG_VIRTUAL is not set
 | |
| +# CONFIG_DEBUG_VM is not set
 | |
| +# CONFIG_DEBUG_VM_PGTABLE is not set
 | |
| +# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
 | |
| +# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
 | |
| +# CONFIG_DEBUG_WX is not set
 | |
| +# CONFIG_DEBUG_ZBOOT is not set
 | |
| +# CONFIG_DECNET is not set
 | |
| +CONFIG_DEFAULT_CUBIC=y
 | |
| +CONFIG_DEFAULT_DEADLINE=y
 | |
| +CONFIG_DEFAULT_HOSTNAME="(none)"
 | |
| +CONFIG_DEFAULT_INIT=""
 | |
| +CONFIG_DEFAULT_IOSCHED="deadline"
 | |
| +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 | |
| +# CONFIG_DEFAULT_NOOP is not set
 | |
| +# CONFIG_DEFAULT_RENO is not set
 | |
| +CONFIG_DEFAULT_SECURITY=""
 | |
| +CONFIG_DEFAULT_SECURITY_DAC=y
 | |
| +# CONFIG_DEFAULT_SECURITY_SELINUX is not set
 | |
| +CONFIG_DEFAULT_TCP_CONG="cubic"
 | |
| +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 | |
| +# CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set
 | |
| +# CONFIG_DELL_LAPTOP is not set
 | |
| +# CONFIG_DELL_RBTN is not set
 | |
| +# CONFIG_DELL_SMBIOS is not set
 | |
| +# CONFIG_DELL_SMO8800 is not set
 | |
| +# CONFIG_DEPRECATED_PARAM_STRUCT is not set
 | |
| +# CONFIG_DETECT_HUNG_TASK is not set
 | |
| +# CONFIG_DEVKMEM is not set
 | |
| +# CONFIG_DEVMEM is not set
 | |
| +CONFIG_DEVPORT=y
 | |
| +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
 | |
| +# CONFIG_DEVTMPFS is not set
 | |
| +# CONFIG_DEVTMPFS_MOUNT is not set
 | |
| +# CONFIG_DEV_DAX is not set
 | |
| +# CONFIG_DGAP is not set
 | |
| +# CONFIG_DGNC is not set
 | |
| +# CONFIG_DHT11 is not set
 | |
| +# CONFIG_DISCONTIGMEM_MANUAL is not set
 | |
| +# CONFIG_DISPLAY_CONNECTOR_ANALOG_TV is not set
 | |
| +# CONFIG_DISPLAY_CONNECTOR_DVI is not set
 | |
| +# CONFIG_DISPLAY_CONNECTOR_HDMI is not set
 | |
| +# CONFIG_DISPLAY_ENCODER_TFP410 is not set
 | |
| +# CONFIG_DISPLAY_ENCODER_TPD12S015 is not set
 | |
| +# CONFIG_DISPLAY_PANEL_DPI is not set
 | |
| +# CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02 is not set
 | |
| +# CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1 is not set
 | |
| +# CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1 is not set
 | |
| +# CONFIG_DL2K is not set
 | |
| +# CONFIG_DLHL60D is not set
 | |
| +# CONFIG_DLM is not set
 | |
| +# CONFIG_DM9000 is not set
 | |
| +# CONFIG_DMABUF_HEAPS is not set
 | |
| +# CONFIG_DMABUF_MOVE_NOTIFY is not set
 | |
| +# CONFIG_DMABUF_SELFTESTS is not set
 | |
| +# CONFIG_DMADEVICES is not set
 | |
| +# CONFIG_DMADEVICES_DEBUG is not set
 | |
| +# CONFIG_DMARD06 is not set
 | |
| +# CONFIG_DMARD09 is not set
 | |
| +# CONFIG_DMARD10 is not set
 | |
| +# CONFIG_DMASCC is not set
 | |
| +# CONFIG_DMATEST is not set
 | |
| +# CONFIG_DMA_API_DEBUG is not set
 | |
| +CONFIG_DMA_COHERENT_POOL=y
 | |
| +CONFIG_DMA_DECLARE_COHERENT=y
 | |
| +# CONFIG_DMA_ENGINE is not set
 | |
| +# CONFIG_DMA_FENCE_TRACE is not set
 | |
| +# CONFIG_DMA_JZ4780 is not set
 | |
| +CONFIG_DMA_NONCOHERENT_MMAP=y
 | |
| +# CONFIG_DMA_NOOP_OPS is not set
 | |
| +# CONFIG_DMA_SHARED_BUFFER is not set
 | |
| +# CONFIG_DMA_VIRT_OPS is not set
 | |
| +# CONFIG_DM_CACHE is not set
 | |
| +# CONFIG_DM_CLONE is not set
 | |
| +# CONFIG_DM_DEBUG is not set
 | |
| +# CONFIG_DM_DELAY is not set
 | |
| +# CONFIG_DM_DUST is not set
 | |
| +# CONFIG_DM_EBS is not set
 | |
| +# CONFIG_DM_ERA is not set
 | |
| +# CONFIG_DM_FLAKEY is not set
 | |
| +# CONFIG_DM_INTEGRITY is not set
 | |
| +# CONFIG_DM_LOG_USERSPACE is not set
 | |
| +# CONFIG_DM_LOG_WRITES is not set
 | |
| +# CONFIG_DM_MQ_DEFAULT is not set
 | |
| +# CONFIG_DM_MULTIPATH is not set
 | |
| +# CONFIG_DM_RAID is not set
 | |
| +# CONFIG_DM_SWITCH is not set
 | |
| +# CONFIG_DM_THIN_PROVISIONING is not set
 | |
| +# CONFIG_DM_UEVENT is not set
 | |
| +# CONFIG_DM_UNSTRIPED is not set
 | |
| +# CONFIG_DM_VERITY is not set
 | |
| +# CONFIG_DM_WRITECACHE is not set
 | |
| +# CONFIG_DM_ZERO is not set
 | |
| +# CONFIG_DNET is not set
 | |
| +# CONFIG_DNOTIFY is not set
 | |
| +# CONFIG_DNS_RESOLVER is not set
 | |
| +CONFIG_DOUBLEFAULT=y
 | |
| +# CONFIG_DP83822_PHY is not set
 | |
| +# CONFIG_DP83848_PHY is not set
 | |
| +# CONFIG_DP83867_PHY is not set
 | |
| +# CONFIG_DP83869_PHY is not set
 | |
| +# CONFIG_DP83TC811_PHY is not set
 | |
| +# CONFIG_DPOT_DAC is not set
 | |
| +# CONFIG_DPS310 is not set
 | |
| +CONFIG_DQL=y
 | |
| +# CONFIG_DRAGONRISE_FF is not set
 | |
| +# CONFIG_DRM is not set
 | |
| +# CONFIG_DRM_AMDGPU is not set
 | |
| +# CONFIG_DRM_AMDGPU_CIK is not set
 | |
| +# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set
 | |
| +# CONFIG_DRM_AMDGPU_SI is not set
 | |
| +# CONFIG_DRM_AMDGPU_USERPTR is not set
 | |
| +# CONFIG_DRM_AMD_ACP is not set
 | |
| +# CONFIG_DRM_AMD_DC_DCN2_0 is not set
 | |
| +# CONFIG_DRM_AMD_DC_DCN3_0 is not set
 | |
| +# CONFIG_DRM_AMD_DC_HDCP is not set
 | |
| +# CONFIG_DRM_AMD_DC_SI is not set
 | |
| +# CONFIG_DRM_ANALOGIX_ANX6345 is not set
 | |
| +# CONFIG_DRM_ANALOGIX_ANX78XX is not set
 | |
| +# CONFIG_DRM_ARCPGU is not set
 | |
| +# CONFIG_DRM_ARMADA is not set
 | |
| +# CONFIG_DRM_AST is not set
 | |
| +# CONFIG_DRM_BOCHS is not set
 | |
| +# CONFIG_DRM_CDNS_DSI is not set
 | |
| +# CONFIG_DRM_CDNS_MHDP8546 is not set
 | |
| +# CONFIG_DRM_CHRONTEL_CH7033 is not set
 | |
| +# CONFIG_DRM_CIRRUS_QEMU is not set
 | |
| +# CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS is not set
 | |
| +# CONFIG_DRM_DEBUG_MM is not set
 | |
| +# CONFIG_DRM_DEBUG_SELFTEST is not set
 | |
| +# CONFIG_DRM_DISPLAY_CONNECTOR is not set
 | |
| +# CONFIG_DRM_DP_AUX_CHARDEV is not set
 | |
| +# CONFIG_DRM_DP_CEC is not set
 | |
| +# CONFIG_DRM_DUMB_VGA_DAC is not set
 | |
| +# CONFIG_DRM_DW_HDMI_CEC is not set
 | |
| +# CONFIG_DRM_ETNAVIV is not set
 | |
| +# CONFIG_DRM_EXYNOS is not set
 | |
| +# CONFIG_DRM_FBDEV_EMULATION is not set
 | |
| +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set
 | |
| +# CONFIG_DRM_FSL_DCU is not set
 | |
| +# CONFIG_DRM_GM12U320 is not set
 | |
| +# CONFIG_DRM_GMA500 is not set
 | |
| +# CONFIG_DRM_HDLCD is not set
 | |
| +# CONFIG_DRM_HISI_HIBMC is not set
 | |
| +# CONFIG_DRM_HISI_KIRIN is not set
 | |
| +# CONFIG_DRM_I2C_ADV7511 is not set
 | |
| +# CONFIG_DRM_I2C_CH7006 is not set
 | |
| +# CONFIG_DRM_I2C_NXP_TDA9950 is not set
 | |
| +# CONFIG_DRM_I2C_NXP_TDA998X is not set
 | |
| +# CONFIG_DRM_I2C_SIL164 is not set
 | |
| +# CONFIG_DRM_I915 is not set
 | |
| +# CONFIG_DRM_KOMEDA is not set
 | |
| +# CONFIG_DRM_LEGACY is not set
 | |
| +# CONFIG_DRM_LIB_RANDOM is not set
 | |
| +# CONFIG_DRM_LIMA is not set
 | |
| +# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
 | |
| +# CONFIG_DRM_LONTIUM_LT9611 is not set
 | |
| +# CONFIG_DRM_LVDS_CODEC is not set
 | |
| +# CONFIG_DRM_LVDS_ENCODER is not set
 | |
| +# CONFIG_DRM_MALI_DISPLAY is not set
 | |
| +# CONFIG_DRM_MCDE is not set
 | |
| +# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
 | |
| +# CONFIG_DRM_MGAG200 is not set
 | |
| +# CONFIG_DRM_MXSFB is not set
 | |
| +# CONFIG_DRM_NOUVEAU is not set
 | |
| +# CONFIG_DRM_NWL_MIPI_DSI is not set
 | |
| +# CONFIG_DRM_NXP_PTN3460 is not set
 | |
| +# CONFIG_DRM_OMAP is not set
 | |
| +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set
 | |
| +# CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D is not set
 | |
| +# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
 | |
| +# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set
 | |
| +# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set
 | |
| +# CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
 | |
| +# CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set
 | |
| +# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
 | |
| +# CONFIG_DRM_PANEL_LG_LG4573 is not set
 | |
| +# CONFIG_DRM_PANEL_LVDS is not set
 | |
| +# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
 | |
| +# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
 | |
| +# CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
 | |
| +# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set
 | |
| +# CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set
 | |
| +# CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set
 | |
| +# CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set
 | |
| +# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set
 | |
| +# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set
 | |
| +# CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set
 | |
| +# CONFIG_DRM_PANEL_RONBO_RB070D30 is not set
 | |
| +# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
 | |
| +# CONFIG_DRM_PANEL_SAMSUNG_S6D16D0 is not set
 | |
| +# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set
 | |
| +# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set
 | |
| +# CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set
 | |
| +# CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01 is not set
 | |
| +# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
 | |
| +# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
 | |
| +# CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set
 | |
| +# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set
 | |
| +# CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set
 | |
| +# CONFIG_DRM_PANEL_SIMPLE is not set
 | |
| +# CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set
 | |
| +# CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
 | |
| +# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
 | |
| +# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
 | |
| +# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
 | |
| +# CONFIG_DRM_PANEL_TPO_TPG110 is not set
 | |
| +# CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set
 | |
| +# CONFIG_DRM_PANFROST is not set
 | |
| +# CONFIG_DRM_PARADE_PS8622 is not set
 | |
| +# CONFIG_DRM_PARADE_PS8640 is not set
 | |
| +# CONFIG_DRM_PL111 is not set
 | |
| +# CONFIG_DRM_QXL is not set
 | |
| +# CONFIG_DRM_RADEON is not set
 | |
| +# CONFIG_DRM_RADEON_USERPTR is not set
 | |
| +# CONFIG_DRM_RCAR_DW_HDMI is not set
 | |
| +# CONFIG_DRM_RCAR_LVDS is not set
 | |
| +# CONFIG_DRM_SII902X is not set
 | |
| +# CONFIG_DRM_SII9234 is not set
 | |
| +# CONFIG_DRM_SIL_SII8620 is not set
 | |
| +# CONFIG_DRM_SIMPLE_BRIDGE is not set
 | |
| +# CONFIG_DRM_STI is not set
 | |
| +# CONFIG_DRM_STM is not set
 | |
| +# CONFIG_DRM_SUN4I is not set
 | |
| +# CONFIG_DRM_THINE_THC63LVD1024 is not set
 | |
| +# CONFIG_DRM_TIDSS is not set
 | |
| +# CONFIG_DRM_TILCDC is not set
 | |
| +# CONFIG_DRM_TINYDRM is not set
 | |
| +# CONFIG_DRM_TI_SN65DSI86 is not set
 | |
| +# CONFIG_DRM_TI_TFP410 is not set
 | |
| +# CONFIG_DRM_TI_TPD12S015 is not set
 | |
| +# CONFIG_DRM_TOSHIBA_TC358762 is not set
 | |
| +# CONFIG_DRM_TOSHIBA_TC358764 is not set
 | |
| +# CONFIG_DRM_TOSHIBA_TC358767 is not set
 | |
| +# CONFIG_DRM_TOSHIBA_TC358768 is not set
 | |
| +# CONFIG_DRM_TOSHIBA_TC358775 is not set
 | |
| +# CONFIG_DRM_UDL is not set
 | |
| +# CONFIG_DRM_VBOXVIDEO is not set
 | |
| +# CONFIG_DRM_VC4_HDMI_CEC is not set
 | |
| +# CONFIG_DRM_VGEM is not set
 | |
| +# CONFIG_DRM_VIRTIO_GPU is not set
 | |
| +# CONFIG_DRM_VKMS is not set
 | |
| +# CONFIG_DRM_VMWGFX is not set
 | |
| +# CONFIG_DRM_XEN is not set
 | |
| +# CONFIG_DS1682 is not set
 | |
| +# CONFIG_DS1803 is not set
 | |
| +# CONFIG_DS4424 is not set
 | |
| +# CONFIG_DST_CACHE is not set
 | |
| +# CONFIG_DTLK is not set
 | |
| +# CONFIG_DUMMY is not set
 | |
| +CONFIG_DUMMY_CONSOLE_COLUMNS=80
 | |
| +CONFIG_DUMMY_CONSOLE_ROWS=25
 | |
| +# CONFIG_DUMMY_IRQ is not set
 | |
| +# CONFIG_DVB_A8293 is not set
 | |
| +# CONFIG_DVB_AF9013 is not set
 | |
| +# CONFIG_DVB_AF9033 is not set
 | |
| +# CONFIG_DVB_AS102 is not set
 | |
| +# CONFIG_DVB_ASCOT2E is not set
 | |
| +# CONFIG_DVB_ATBM8830 is not set
 | |
| +# CONFIG_DVB_AU8522_DTV is not set
 | |
| +# CONFIG_DVB_AU8522_V4L is not set
 | |
| +# CONFIG_DVB_B2C2_FLEXCOP_USB is not set
 | |
| +# CONFIG_DVB_BCM3510 is not set
 | |
| +# CONFIG_DVB_CORE is not set
 | |
| +# CONFIG_DVB_CX22700 is not set
 | |
| +# CONFIG_DVB_CX22702 is not set
 | |
| +# CONFIG_DVB_CX24110 is not set
 | |
| +# CONFIG_DVB_CX24116 is not set
 | |
| +# CONFIG_DVB_CX24117 is not set
 | |
| +# CONFIG_DVB_CX24120 is not set
 | |
| +# CONFIG_DVB_CX24123 is not set
 | |
| +# CONFIG_DVB_CXD2099 is not set
 | |
| +# CONFIG_DVB_CXD2820R is not set
 | |
| +# CONFIG_DVB_CXD2841ER is not set
 | |
| +# CONFIG_DVB_CXD2880 is not set
 | |
| +# CONFIG_DVB_DEMUX_SECTION_LOSS_LOG is not set
 | |
| +# CONFIG_DVB_DIB3000MB is not set
 | |
| +# CONFIG_DVB_DIB3000MC is not set
 | |
| +# CONFIG_DVB_DIB7000M is not set
 | |
| +# CONFIG_DVB_DIB7000P is not set
 | |
| +# CONFIG_DVB_DIB8000 is not set
 | |
| +# CONFIG_DVB_DIB9000 is not set
 | |
| +# CONFIG_DVB_DRX39XYJ is not set
 | |
| +# CONFIG_DVB_DRXD is not set
 | |
| +# CONFIG_DVB_DRXK is not set
 | |
| +# CONFIG_DVB_DS3000 is not set
 | |
| +# CONFIG_DVB_DUMMY_FE is not set
 | |
| +# CONFIG_DVB_DYNAMIC_MINORS is not set
 | |
| +# CONFIG_DVB_EC100 is not set
 | |
| +# CONFIG_DVB_FIREDTV is not set
 | |
| +# CONFIG_DVB_HELENE is not set
 | |
| +# CONFIG_DVB_HORUS3A is not set
 | |
| +# CONFIG_DVB_ISL6405 is not set
 | |
| +# CONFIG_DVB_ISL6421 is not set
 | |
| +# CONFIG_DVB_ISL6423 is not set
 | |
| +# CONFIG_DVB_IX2505V is not set
 | |
| +# CONFIG_DVB_L64781 is not set
 | |
| +# CONFIG_DVB_LG2160 is not set
 | |
| +# CONFIG_DVB_LGDT3305 is not set
 | |
| +# CONFIG_DVB_LGDT3306A is not set
 | |
| +# CONFIG_DVB_LGDT330X is not set
 | |
| +# CONFIG_DVB_LGS8GL5 is not set
 | |
| +# CONFIG_DVB_LGS8GXX is not set
 | |
| +# CONFIG_DVB_LNBH25 is not set
 | |
| +# CONFIG_DVB_LNBH29 is not set
 | |
| +# CONFIG_DVB_LNBP21 is not set
 | |
| +# CONFIG_DVB_LNBP22 is not set
 | |
| +# CONFIG_DVB_M88DS3103 is not set
 | |
| +# CONFIG_DVB_M88RS2000 is not set
 | |
| +CONFIG_DVB_MAX_ADAPTERS=16
 | |
| +# CONFIG_DVB_MB86A16 is not set
 | |
| +# CONFIG_DVB_MB86A20S is not set
 | |
| +# CONFIG_DVB_MMAP is not set
 | |
| +# CONFIG_DVB_MN88443X is not set
 | |
| +# CONFIG_DVB_MN88472 is not set
 | |
| +# CONFIG_DVB_MN88473 is not set
 | |
| +# CONFIG_DVB_MT312 is not set
 | |
| +# CONFIG_DVB_MT352 is not set
 | |
| +# CONFIG_DVB_MXL5XX is not set
 | |
| +# CONFIG_DVB_NET is not set
 | |
| +# CONFIG_DVB_NXT200X is not set
 | |
| +# CONFIG_DVB_NXT6000 is not set
 | |
| +# CONFIG_DVB_OR51132 is not set
 | |
| +# CONFIG_DVB_OR51211 is not set
 | |
| +# CONFIG_DVB_PLATFORM_DRIVERS is not set
 | |
| +# CONFIG_DVB_PLL is not set
 | |
| +# CONFIG_DVB_RTL2830 is not set
 | |
| +# CONFIG_DVB_RTL2832 is not set
 | |
| +# CONFIG_DVB_RTL2832_SDR is not set
 | |
| +# CONFIG_DVB_S5H1409 is not set
 | |
| +# CONFIG_DVB_S5H1411 is not set
 | |
| +# CONFIG_DVB_S5H1420 is not set
 | |
| +# CONFIG_DVB_S5H1432 is not set
 | |
| +# CONFIG_DVB_S921 is not set
 | |
| +# CONFIG_DVB_SI2165 is not set
 | |
| +# CONFIG_DVB_SI2168 is not set
 | |
| +# CONFIG_DVB_SI21XX is not set
 | |
| +# CONFIG_DVB_SP2 is not set
 | |
| +# CONFIG_DVB_SP8870 is not set
 | |
| +# CONFIG_DVB_SP887X is not set
 | |
| +# CONFIG_DVB_STB0899 is not set
 | |
| +# CONFIG_DVB_STB6000 is not set
 | |
| +# CONFIG_DVB_STB6100 is not set
 | |
| +# CONFIG_DVB_STV0288 is not set
 | |
| +# CONFIG_DVB_STV0297 is not set
 | |
| +# CONFIG_DVB_STV0299 is not set
 | |
| +# CONFIG_DVB_STV0367 is not set
 | |
| +# CONFIG_DVB_STV0900 is not set
 | |
| +# CONFIG_DVB_STV090x is not set
 | |
| +# CONFIG_DVB_STV0910 is not set
 | |
| +# CONFIG_DVB_STV6110 is not set
 | |
| +# CONFIG_DVB_STV6110x is not set
 | |
| +# CONFIG_DVB_STV6111 is not set
 | |
| +# CONFIG_DVB_TC90522 is not set
 | |
| +# CONFIG_DVB_TDA10021 is not set
 | |
| +# CONFIG_DVB_TDA10023 is not set
 | |
| +# CONFIG_DVB_TDA10048 is not set
 | |
| +# CONFIG_DVB_TDA1004X is not set
 | |
| +# CONFIG_DVB_TDA10071 is not set
 | |
| +# CONFIG_DVB_TDA10086 is not set
 | |
| +# CONFIG_DVB_TDA18271C2DD is not set
 | |
| +# CONFIG_DVB_TDA665x is not set
 | |
| +# CONFIG_DVB_TDA8083 is not set
 | |
| +# CONFIG_DVB_TDA8261 is not set
 | |
| +# CONFIG_DVB_TDA826X is not set
 | |
| +# CONFIG_DVB_TEST_DRIVERS is not set
 | |
| +# CONFIG_DVB_TS2020 is not set
 | |
| +# CONFIG_DVB_TTUSB_BUDGET is not set
 | |
| +# CONFIG_DVB_TTUSB_DEC is not set
 | |
| +# CONFIG_DVB_TUA6100 is not set
 | |
| +# CONFIG_DVB_TUNER_CX24113 is not set
 | |
| +# CONFIG_DVB_TUNER_DIB0070 is not set
 | |
| +# CONFIG_DVB_TUNER_DIB0090 is not set
 | |
| +# CONFIG_DVB_TUNER_ITD1000 is not set
 | |
| +# CONFIG_DVB_ULE_DEBUG is not set
 | |
| +# CONFIG_DVB_USB_V2 is not set
 | |
| +# CONFIG_DVB_VES1820 is not set
 | |
| +# CONFIG_DVB_VES1X93 is not set
 | |
| +# CONFIG_DVB_ZD1301_DEMOD is not set
 | |
| +# CONFIG_DVB_ZL10036 is not set
 | |
| +# CONFIG_DVB_ZL10039 is not set
 | |
| +# CONFIG_DVB_ZL10353 is not set
 | |
| +# CONFIG_DWC_XLGMAC is not set
 | |
| +# CONFIG_DWMAC_DWC_QOS_ETH is not set
 | |
| +# CONFIG_DWMAC_INTEL_PLAT is not set
 | |
| +# CONFIG_DWMAC_IPQ806X is not set
 | |
| +# CONFIG_DWMAC_LPC18XX is not set
 | |
| +# CONFIG_DWMAC_MESON is not set
 | |
| +# CONFIG_DWMAC_ROCKCHIP is not set
 | |
| +# CONFIG_DWMAC_SOCFPGA is not set
 | |
| +# CONFIG_DWMAC_STI is not set
 | |
| +# CONFIG_DW_AXI_DMAC is not set
 | |
| +# CONFIG_DW_DMAC is not set
 | |
| +# CONFIG_DW_DMAC_PCI is not set
 | |
| +# CONFIG_DW_EDMA is not set
 | |
| +# CONFIG_DW_EDMA_PCIE is not set
 | |
| +# CONFIG_DW_WATCHDOG is not set
 | |
| +# CONFIG_DYNAMIC_DEBUG is not set
 | |
| +CONFIG_DYNAMIC_DEBUG_CORE=y
 | |
| +# CONFIG_E100 is not set
 | |
| +# CONFIG_E1000 is not set
 | |
| +# CONFIG_E1000E is not set
 | |
| +# CONFIG_E1000E_HWTS is not set
 | |
| +# CONFIG_EARLY_PRINTK_8250 is not set
 | |
| +# CONFIG_EARLY_PRINTK_USB_XDBC is not set
 | |
| +# CONFIG_EBC_C384_WDT is not set
 | |
| +# CONFIG_ECHO is not set
 | |
| +# CONFIG_ECRYPT_FS is not set
 | |
| +# CONFIG_EDAC is not set
 | |
| +# CONFIG_EEEPC_LAPTOP is not set
 | |
| +# CONFIG_EEPROM_93CX6 is not set
 | |
| +# CONFIG_EEPROM_93XX46 is not set
 | |
| +# CONFIG_EEPROM_AT24 is not set
 | |
| +# CONFIG_EEPROM_AT25 is not set
 | |
| +# CONFIG_EEPROM_DIGSY_MTC_CFG is not set
 | |
| +# CONFIG_EEPROM_EE1004 is not set
 | |
| +# CONFIG_EEPROM_IDT_89HPESX is not set
 | |
| +# CONFIG_EEPROM_LEGACY is not set
 | |
| +# CONFIG_EEPROM_MAX6875 is not set
 | |
| +# CONFIG_EFI is not set
 | |
| +CONFIG_EFI_PARTITION=y
 | |
| +# CONFIG_EFS_FS is not set
 | |
| +CONFIG_ELFCORE=y
 | |
| +# CONFIG_ELF_CORE is not set
 | |
| +# CONFIG_EMAC_ROCKCHIP is not set
 | |
| +CONFIG_EMBEDDED=y
 | |
| +# CONFIG_EM_TIMER_STI is not set
 | |
| +# CONFIG_ENABLE_MUST_CHECK is not set
 | |
| +CONFIG_ENABLE_WARN_DEPRECATED=y
 | |
| +# CONFIG_ENA_ETHERNET is not set
 | |
| +# CONFIG_ENC28J60 is not set
 | |
| +# CONFIG_ENCLOSURE_SERVICES is not set
 | |
| +# CONFIG_ENCRYPTED_KEYS is not set
 | |
| +# CONFIG_ENCX24J600 is not set
 | |
| +# CONFIG_ENERGY_MODEL is not set
 | |
| +# CONFIG_ENIC is not set
 | |
| +# CONFIG_ENVELOPE_DETECTOR is not set
 | |
| +# CONFIG_EPAPR_PARAVIRT is not set
 | |
| +# CONFIG_EPIC100 is not set
 | |
| +CONFIG_EPOLL=y
 | |
| +# CONFIG_EQUALIZER is not set
 | |
| +# CONFIG_EROFS_FS is not set
 | |
| +# CONFIG_ET131X is not set
 | |
| +CONFIG_ETHERNET=y
 | |
| +# CONFIG_ETHOC is not set
 | |
| +# CONFIG_ETHTOOL_NETLINK is not set
 | |
| +CONFIG_EVENTFD=y
 | |
| +# CONFIG_EVM is not set
 | |
| +# CONFIG_EXFAT_FS is not set
 | |
| +CONFIG_EXPERT=y
 | |
| +CONFIG_EXPORTFS=y
 | |
| +# CONFIG_EXPORTFS_BLOCK_OPS is not set
 | |
| +# CONFIG_EXT2_FS is not set
 | |
| +CONFIG_EXT2_FS_XATTR=y
 | |
| +# CONFIG_EXT3_FS is not set
 | |
| +# CONFIG_EXT4_DEBUG is not set
 | |
| +# CONFIG_EXT4_ENCRYPTION is not set
 | |
| +# CONFIG_EXT4_FS is not set
 | |
| +# CONFIG_EXT4_FS_POSIX_ACL is not set
 | |
| +# CONFIG_EXT4_FS_SECURITY is not set
 | |
| +CONFIG_EXT4_USE_FOR_EXT2=y
 | |
| +# CONFIG_EXTCON is not set
 | |
| +# CONFIG_EXTCON_ADC_JACK is not set
 | |
| +# CONFIG_EXTCON_ARIZONA is not set
 | |
| +# CONFIG_EXTCON_AXP288 is not set
 | |
| +# CONFIG_EXTCON_FSA9480 is not set
 | |
| +# CONFIG_EXTCON_GPIO is not set
 | |
| +# CONFIG_EXTCON_INTEL_INT3496 is not set
 | |
| +# CONFIG_EXTCON_MAX3355 is not set
 | |
| +# CONFIG_EXTCON_PTN5150 is not set
 | |
| +# CONFIG_EXTCON_QCOM_SPMI_MISC is not set
 | |
| +# CONFIG_EXTCON_RT8973A is not set
 | |
| +# CONFIG_EXTCON_SM5502 is not set
 | |
| +# CONFIG_EXTCON_USB_GPIO is not set
 | |
| +CONFIG_EXTRA_FIRMWARE=""
 | |
| +CONFIG_EXTRA_TARGETS=""
 | |
| +# CONFIG_EXYNOS_ADC is not set
 | |
| +# CONFIG_EXYNOS_VIDEO is not set
 | |
| +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set
 | |
| +# CONFIG_EZX_PCAP is not set
 | |
| +# CONFIG_F2FS_CHECK_FS is not set
 | |
| +# CONFIG_F2FS_FAULT_INJECTION is not set
 | |
| +# CONFIG_F2FS_FS is not set
 | |
| +# CONFIG_F2FS_FS_COMPRESSION is not set
 | |
| +# CONFIG_F2FS_FS_ENCRYPTION is not set
 | |
| +# CONFIG_F2FS_FS_POSIX_ACL is not set
 | |
| +# CONFIG_F2FS_FS_SECURITY is not set
 | |
| +CONFIG_F2FS_FS_XATTR=y
 | |
| +# CONFIG_F2FS_IO_TRACE is not set
 | |
| +CONFIG_F2FS_STAT_FS=y
 | |
| +# CONFIG_FAILOVER is not set
 | |
| +# CONFIG_FAIR_GROUP_SCHED is not set
 | |
| +# CONFIG_FANOTIFY is not set
 | |
| +# CONFIG_FANOTIFY_ACCESS_PERMISSIONS is not set
 | |
| +CONFIG_FAT_DEFAULT_CODEPAGE=437
 | |
| +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 | |
| +# CONFIG_FAT_DEFAULT_UTF8 is not set
 | |
| +# CONFIG_FAT_FS is not set
 | |
| +# CONFIG_FAULT_INJECTION is not set
 | |
| +# CONFIG_FB is not set
 | |
| +# CONFIG_FB_3DFX is not set
 | |
| +# CONFIG_FB_ARC is not set
 | |
| +# CONFIG_FB_ARK is not set
 | |
| +# CONFIG_FB_ARMCLCD is not set
 | |
| +# CONFIG_FB_ASILIANT is not set
 | |
| +# CONFIG_FB_ATY is not set
 | |
| +# CONFIG_FB_ATY128 is not set
 | |
| +# CONFIG_FB_AUO_K190X is not set
 | |
| +# CONFIG_FB_BACKLIGHT is not set
 | |
| +# CONFIG_FB_BIG_ENDIAN is not set
 | |
| +# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 | |
| +# CONFIG_FB_BOTH_ENDIAN is not set
 | |
| +# CONFIG_FB_BROADSHEET is not set
 | |
| +# CONFIG_FB_CARMINE is not set
 | |
| +# CONFIG_FB_CFB_COPYAREA is not set
 | |
| +# CONFIG_FB_CFB_FILLRECT is not set
 | |
| +# CONFIG_FB_CFB_IMAGEBLIT is not set
 | |
| +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
 | |
| +# CONFIG_FB_CIRRUS is not set
 | |
| +# CONFIG_FB_CYBER2000 is not set
 | |
| +# CONFIG_FB_DA8XX is not set
 | |
| +# CONFIG_FB_DDC is not set
 | |
| +# CONFIG_FB_FLEX is not set
 | |
| +# CONFIG_FB_FOREIGN_ENDIAN is not set
 | |
| +# CONFIG_FB_GEODE is not set
 | |
| +# CONFIG_FB_GOLDFISH is not set
 | |
| +# CONFIG_FB_HGA is not set
 | |
| +# CONFIG_FB_I740 is not set
 | |
| +# CONFIG_FB_IBM_GXT4500 is not set
 | |
| +# CONFIG_FB_IMSTT is not set
 | |
| +# CONFIG_FB_IMX is not set
 | |
| +# CONFIG_FB_KYRO is not set
 | |
| +# CONFIG_FB_LE80578 is not set
 | |
| +# CONFIG_FB_LITTLE_ENDIAN is not set
 | |
| +# CONFIG_FB_MACMODES is not set
 | |
| +# CONFIG_FB_MATROX is not set
 | |
| +# CONFIG_FB_MB862XX is not set
 | |
| +# CONFIG_FB_METRONOME is not set
 | |
| +# CONFIG_FB_MODE_HELPERS is not set
 | |
| +# CONFIG_FB_MXS is not set
 | |
| +# CONFIG_FB_N411 is not set
 | |
| +# CONFIG_FB_NEOMAGIC is not set
 | |
| +CONFIG_FB_NOTIFY=y
 | |
| +# CONFIG_FB_NVIDIA is not set
 | |
| +# CONFIG_FB_OF is not set
 | |
| +# CONFIG_FB_OMAP2 is not set
 | |
| +# CONFIG_FB_OPENCORES is not set
 | |
| +# CONFIG_FB_PM2 is not set
 | |
| +# CONFIG_FB_PM3 is not set
 | |
| +# CONFIG_FB_PS3 is not set
 | |
| +# CONFIG_FB_PXA is not set
 | |
| +# CONFIG_FB_RADEON is not set
 | |
| +# CONFIG_FB_RIVA is not set
 | |
| +# CONFIG_FB_S1D13XXX is not set
 | |
| +# CONFIG_FB_S3 is not set
 | |
| +# CONFIG_FB_SAVAGE is not set
 | |
| +# CONFIG_FB_SIMPLE is not set
 | |
| +# CONFIG_FB_SIS is not set
 | |
| +# CONFIG_FB_SM712 is not set
 | |
| +# CONFIG_FB_SM750 is not set
 | |
| +# CONFIG_FB_SMSCUFX is not set
 | |
| +# CONFIG_FB_SSD1307 is not set
 | |
| +# CONFIG_FB_SVGALIB is not set
 | |
| +# CONFIG_FB_SYS_COPYAREA is not set
 | |
| +# CONFIG_FB_SYS_FILLRECT is not set
 | |
| +# CONFIG_FB_SYS_FOPS is not set
 | |
| +# CONFIG_FB_SYS_IMAGEBLIT is not set
 | |
| +# CONFIG_FB_TFT is not set
 | |
| +# CONFIG_FB_TFT_AGM1264K_FL is not set
 | |
| +# CONFIG_FB_TFT_BD663474 is not set
 | |
| +# CONFIG_FB_TFT_FBTFT_DEVICE is not set
 | |
| +# CONFIG_FB_TFT_HX8340BN is not set
 | |
| +# CONFIG_FB_TFT_HX8347D is not set
 | |
| +# CONFIG_FB_TFT_HX8353D is not set
 | |
| +# CONFIG_FB_TFT_HX8357D is not set
 | |
| +# CONFIG_FB_TFT_ILI9163 is not set
 | |
| +# CONFIG_FB_TFT_ILI9320 is not set
 | |
| +# CONFIG_FB_TFT_ILI9325 is not set
 | |
| +# CONFIG_FB_TFT_ILI9340 is not set
 | |
| +# CONFIG_FB_TFT_ILI9341 is not set
 | |
| +# CONFIG_FB_TFT_ILI9481 is not set
 | |
| +# CONFIG_FB_TFT_ILI9486 is not set
 | |
| +# CONFIG_FB_TFT_PCD8544 is not set
 | |
| +# CONFIG_FB_TFT_RA8875 is not set
 | |
| +# CONFIG_FB_TFT_S6D02A1 is not set
 | |
| +# CONFIG_FB_TFT_S6D1121 is not set
 | |
| +# CONFIG_FB_TFT_SEPS525 is not set
 | |
| +# CONFIG_FB_TFT_SH1106 is not set
 | |
| +# CONFIG_FB_TFT_SSD1289 is not set
 | |
| +# CONFIG_FB_TFT_SSD1305 is not set
 | |
| +# CONFIG_FB_TFT_SSD1306 is not set
 | |
| +# CONFIG_FB_TFT_SSD1325 is not set
 | |
| +# CONFIG_FB_TFT_SSD1331 is not set
 | |
| +# CONFIG_FB_TFT_SSD1351 is not set
 | |
| +# CONFIG_FB_TFT_ST7735R is not set
 | |
| +# CONFIG_FB_TFT_ST7789V is not set
 | |
| +# CONFIG_FB_TFT_TINYLCD is not set
 | |
| +# CONFIG_FB_TFT_TLS8204 is not set
 | |
| +# CONFIG_FB_TFT_UC1611 is not set
 | |
| +# CONFIG_FB_TFT_UC1701 is not set
 | |
| +# CONFIG_FB_TFT_UPD161704 is not set
 | |
| +# CONFIG_FB_TFT_WATTEROTT is not set
 | |
| +# CONFIG_FB_TILEBLITTING is not set
 | |
| +# CONFIG_FB_TMIO is not set
 | |
| +# CONFIG_FB_TRIDENT is not set
 | |
| +# CONFIG_FB_UDL is not set
 | |
| +# CONFIG_FB_UVESA is not set
 | |
| +# CONFIG_FB_VGA16 is not set
 | |
| +# CONFIG_FB_VIA is not set
 | |
| +# CONFIG_FB_VIRTUAL is not set
 | |
| +# CONFIG_FB_VOODOO1 is not set
 | |
| +# CONFIG_FB_VT8623 is not set
 | |
| +# CONFIG_FB_XGI is not set
 | |
| +# CONFIG_FCOE is not set
 | |
| +# CONFIG_FCOE_FNIC is not set
 | |
| +# CONFIG_FDDI is not set
 | |
| +# CONFIG_FEALNX is not set
 | |
| +# CONFIG_FENCE_TRACE is not set
 | |
| +# CONFIG_FHANDLE is not set
 | |
| +CONFIG_FIB_RULES=y
 | |
| +# CONFIG_FIELDBUS_DEV is not set
 | |
| +CONFIG_FILE_LOCKING=y
 | |
| +# CONFIG_FIND_BIT_BENCHMARK is not set
 | |
| +# CONFIG_FIREWIRE is not set
 | |
| +# CONFIG_FIREWIRE_NOSY is not set
 | |
| +# CONFIG_FIREWIRE_SERIAL is not set
 | |
| +# CONFIG_FIRMWARE_EDID is not set
 | |
| +# CONFIG_FIRMWARE_IN_KERNEL is not set
 | |
| +# CONFIG_FIRMWARE_MEMMAP is not set
 | |
| +# CONFIG_FIT_PARTITION is not set
 | |
| +# CONFIG_FIXED_PHY is not set
 | |
| +CONFIG_FLATMEM=y
 | |
| +CONFIG_FLATMEM_MANUAL=y
 | |
| +CONFIG_FLAT_NODE_MEM_MAP=y
 | |
| +# CONFIG_FM10K is not set
 | |
| +# CONFIG_FMC is not set
 | |
| +# CONFIG_FONTS is not set
 | |
| +# CONFIG_FONT_6x8 is not set
 | |
| +# CONFIG_FONT_TER16x32 is not set
 | |
| +# CONFIG_FORCEDETH is not set
 | |
| +CONFIG_FORCE_MAX_ZONEORDER=11
 | |
| +CONFIG_FORTIFY_SOURCE=y
 | |
| +# CONFIG_FPGA is not set
 | |
| +# CONFIG_FRAMEBUFFER_CONSOLE is not set
 | |
| +# CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER is not set
 | |
| +# CONFIG_FRAME_POINTER is not set
 | |
| +CONFIG_FRAME_WARN=1024
 | |
| +# CONFIG_FREEZER is not set
 | |
| +# CONFIG_FRONTSWAP is not set
 | |
| +# CONFIG_FSCACHE is not set
 | |
| +# CONFIG_FSI is not set
 | |
| +# CONFIG_FSL_EDMA is not set
 | |
| +# CONFIG_FSL_ERRATUM_A008585 is not set
 | |
| +# CONFIG_FSL_MC_BUS is not set
 | |
| +# CONFIG_FSL_PQ_MDIO is not set
 | |
| +# CONFIG_FSL_QDMA is not set
 | |
| +# CONFIG_FSL_RCPM is not set
 | |
| +# CONFIG_FSL_XGMAC_MDIO is not set
 | |
| +CONFIG_FSNOTIFY=y
 | |
| +# CONFIG_FS_DAX is not set
 | |
| +# CONFIG_FS_ENCRYPTION is not set
 | |
| +# CONFIG_FS_POSIX_ACL is not set
 | |
| +# CONFIG_FS_VERITY is not set
 | |
| +# CONFIG_FTGMAC100 is not set
 | |
| +# CONFIG_FTL is not set
 | |
| +# CONFIG_FTMAC100 is not set
 | |
| +# CONFIG_FTRACE is not set
 | |
| +# CONFIG_FTRACE_STARTUP_TEST is not set
 | |
| +# CONFIG_FTR_FIXUP_SELFTEST is not set
 | |
| +# CONFIG_FTWDT010_WATCHDOG is not set
 | |
| +# CONFIG_FUJITSU_ES is not set
 | |
| +# CONFIG_FUJITSU_LAPTOP is not set
 | |
| +# CONFIG_FUJITSU_TABLET is not set
 | |
| +# CONFIG_FUNCTION_TRACER is not set
 | |
| +# CONFIG_FUSE_FS is not set
 | |
| +# CONFIG_FUSION is not set
 | |
| +# CONFIG_FUSION_FC is not set
 | |
| +# CONFIG_FUSION_SAS is not set
 | |
| +# CONFIG_FUSION_SPI is not set
 | |
| +CONFIG_FUTEX=y
 | |
| +CONFIG_FUTEX_PI=y
 | |
| +# CONFIG_FW_CFG_SYSFS is not set
 | |
| +CONFIG_FW_LOADER=y
 | |
| +# CONFIG_FW_LOADER_COMPRESS is not set
 | |
| +CONFIG_FW_LOADER_USER_HELPER=y
 | |
| +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
 | |
| +# CONFIG_FXAS21002C is not set
 | |
| +# CONFIG_FXOS8700_I2C is not set
 | |
| +# CONFIG_FXOS8700_SPI is not set
 | |
| +CONFIG_GACT_PROB=y
 | |
| +# CONFIG_GADGET_UAC1 is not set
 | |
| +# CONFIG_GAMEPORT is not set
 | |
| +# CONFIG_GATEWORKS_GW16083 is not set
 | |
| +# CONFIG_GCC_PLUGINS is not set
 | |
| +# CONFIG_GCOV is not set
 | |
| +# CONFIG_GCOV_KERNEL is not set
 | |
| +# CONFIG_GDB_SCRIPTS is not set
 | |
| +# CONFIG_GEMINI_ETHERNET is not set
 | |
| +# CONFIG_GENERIC_ADC_BATTERY is not set
 | |
| +# CONFIG_GENERIC_ADC_THERMAL is not set
 | |
| +CONFIG_GENERIC_CALIBRATE_DELAY=y
 | |
| +# CONFIG_GENERIC_CPU_DEVICES is not set
 | |
| +CONFIG_GENERIC_HWEIGHT=y
 | |
| +# CONFIG_GENERIC_IRQ_DEBUGFS is not set
 | |
| +CONFIG_GENERIC_IRQ_IPI=y
 | |
| +CONFIG_GENERIC_IRQ_PROBE=y
 | |
| +CONFIG_GENERIC_NET_UTILS=y
 | |
| +# CONFIG_GENERIC_PHY is not set
 | |
| +CONFIG_GENERIC_PTDUMP=y
 | |
| +CONFIG_GENERIC_VDSO_TIME_NS=y
 | |
| +# CONFIG_GENEVE is not set
 | |
| +# CONFIG_GENWQE is not set
 | |
| +# CONFIG_GFS2_FS is not set
 | |
| +# CONFIG_GIGASET_CAPI is not set
 | |
| +# CONFIG_GIGASET_DEBUG is not set
 | |
| +# CONFIG_GIGASET_DUMMYLL is not set
 | |
| +# CONFIG_GLOB_SELFTEST is not set
 | |
| +# CONFIG_GNSS is not set
 | |
| +# CONFIG_GOLDFISH is not set
 | |
| +# CONFIG_GOOGLE_FIRMWARE is not set
 | |
| +# CONFIG_GP2AP002 is not set
 | |
| +# CONFIG_GP2AP020A00F is not set
 | |
| +# CONFIG_GPD_POCKET_FAN is not set
 | |
| +# CONFIG_GPIOLIB is not set
 | |
| +CONFIG_GPIOLIB_FASTPATH_LIMIT=512
 | |
| +# CONFIG_GPIO_104_DIO_48E is not set
 | |
| +# CONFIG_GPIO_104_IDIO_16 is not set
 | |
| +# CONFIG_GPIO_104_IDI_48 is not set
 | |
| +# CONFIG_GPIO_74X164 is not set
 | |
| +# CONFIG_GPIO_74XX_MMIO is not set
 | |
| +# CONFIG_GPIO_ADNP is not set
 | |
| +# CONFIG_GPIO_ADP5588 is not set
 | |
| +# CONFIG_GPIO_AGGREGATOR is not set
 | |
| +# CONFIG_GPIO_ALTERA is not set
 | |
| +# CONFIG_GPIO_AMD8111 is not set
 | |
| +# CONFIG_GPIO_AMDPT is not set
 | |
| +# CONFIG_GPIO_AMD_FCH is not set
 | |
| +# CONFIG_GPIO_BCM_KONA is not set
 | |
| +# CONFIG_GPIO_BT8XX is not set
 | |
| +# CONFIG_GPIO_CADENCE is not set
 | |
| +# CONFIG_GPIO_CDEV is not set
 | |
| +# CONFIG_GPIO_CS5535 is not set
 | |
| +# CONFIG_GPIO_DWAPB is not set
 | |
| +# CONFIG_GPIO_EM is not set
 | |
| +# CONFIG_GPIO_EXAR is not set
 | |
| +# CONFIG_GPIO_F7188X is not set
 | |
| +# CONFIG_GPIO_FTGPIO010 is not set
 | |
| +# CONFIG_GPIO_GENERIC_PLATFORM is not set
 | |
| +# CONFIG_GPIO_GPIO_MM is not set
 | |
| +# CONFIG_GPIO_GRGPIO is not set
 | |
| +# CONFIG_GPIO_GW_PLD is not set
 | |
| +# CONFIG_GPIO_HLWD is not set
 | |
| +# CONFIG_GPIO_ICH is not set
 | |
| +# CONFIG_GPIO_IT87 is not set
 | |
| +# CONFIG_GPIO_LOGICVC is not set
 | |
| +# CONFIG_GPIO_LYNXPOINT is not set
 | |
| +# CONFIG_GPIO_MAX3191X is not set
 | |
| +# CONFIG_GPIO_MAX7300 is not set
 | |
| +# CONFIG_GPIO_MAX7301 is not set
 | |
| +# CONFIG_GPIO_MAX732X is not set
 | |
| +# CONFIG_GPIO_MB86S7X is not set
 | |
| +# CONFIG_GPIO_MC33880 is not set
 | |
| +# CONFIG_GPIO_MCP23S08 is not set
 | |
| +# CONFIG_GPIO_ML_IOH is not set
 | |
| +# CONFIG_GPIO_MOCKUP is not set
 | |
| +# CONFIG_GPIO_MPC8XXX is not set
 | |
| +# CONFIG_GPIO_PCA953X is not set
 | |
| +# CONFIG_GPIO_PCA953X_IRQ is not set
 | |
| +# CONFIG_GPIO_PCA9570 is not set
 | |
| +# CONFIG_GPIO_PCF857X is not set
 | |
| +# CONFIG_GPIO_PCH is not set
 | |
| +# CONFIG_GPIO_PCIE_IDIO_24 is not set
 | |
| +# CONFIG_GPIO_PCI_IDIO_16 is not set
 | |
| +# CONFIG_GPIO_PISOSR is not set
 | |
| +# CONFIG_GPIO_PL061 is not set
 | |
| +# CONFIG_GPIO_RCAR is not set
 | |
| +# CONFIG_GPIO_RDC321X is not set
 | |
| +# CONFIG_GPIO_SAMA5D2_PIOBU is not set
 | |
| +# CONFIG_GPIO_SCH is not set
 | |
| +# CONFIG_GPIO_SCH311X is not set
 | |
| +# CONFIG_GPIO_SIFIVE is not set
 | |
| +# CONFIG_GPIO_SX150X is not set
 | |
| +# CONFIG_GPIO_SYSCON is not set
 | |
| +CONFIG_GPIO_SYSFS=y
 | |
| +# CONFIG_GPIO_TPIC2810 is not set
 | |
| +# CONFIG_GPIO_TS4900 is not set
 | |
| +# CONFIG_GPIO_TS5500 is not set
 | |
| +# CONFIG_GPIO_VX855 is not set
 | |
| +# CONFIG_GPIO_WATCHDOG is not set
 | |
| +# CONFIG_GPIO_WINBOND is not set
 | |
| +# CONFIG_GPIO_WS16C48 is not set
 | |
| +# CONFIG_GPIO_XGENE is not set
 | |
| +# CONFIG_GPIO_XILINX is not set
 | |
| +# CONFIG_GPIO_XRA1403 is not set
 | |
| +# CONFIG_GPIO_ZEVIO is not set
 | |
| +# CONFIG_GPIO_ZX is not set
 | |
| +# CONFIG_GREENASIA_FF is not set
 | |
| +# CONFIG_GREYBUS is not set
 | |
| +# CONFIG_GS_FPGABOOT is not set
 | |
| +# CONFIG_GTP is not set
 | |
| +# CONFIG_GUP_BENCHMARK is not set
 | |
| +# CONFIG_GVE is not set
 | |
| +# CONFIG_HABANA_AI is not set
 | |
| +# CONFIG_HAMACHI is not set
 | |
| +# CONFIG_HAMRADIO is not set
 | |
| +# CONFIG_HAPPYMEAL is not set
 | |
| +CONFIG_HARDENED_USERCOPY=y
 | |
| +# CONFIG_HARDENED_USERCOPY_FALLBACK is not set
 | |
| +# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set
 | |
| +CONFIG_HARDEN_EL2_VECTORS=y
 | |
| +# CONFIG_HARDLOCKUP_DETECTOR is not set
 | |
| +# CONFIG_HCALL_STATS is not set
 | |
| +# CONFIG_HDC100X is not set
 | |
| +# CONFIG_HDC2010 is not set
 | |
| +# CONFIG_HDLC is not set
 | |
| +# CONFIG_HDLC_CISCO is not set
 | |
| +# CONFIG_HDLC_FR is not set
 | |
| +# CONFIG_HDLC_PPP is not set
 | |
| +# CONFIG_HDLC_RAW is not set
 | |
| +# CONFIG_HDLC_RAW_ETH is not set
 | |
| +# CONFIG_HDMI_LPE_AUDIO is not set
 | |
| +# CONFIG_HDQ_MASTER_OMAP is not set
 | |
| +# CONFIG_HEADERS_CHECK is not set
 | |
| +# CONFIG_HEADERS_INSTALL is not set
 | |
| +# CONFIG_HEADER_TEST is not set
 | |
| +# CONFIG_HERMES is not set
 | |
| +# CONFIG_HFSPLUS_FS is not set
 | |
| +# CONFIG_HFSPLUS_FS_POSIX_ACL is not set
 | |
| +# CONFIG_HFS_FS is not set
 | |
| +# CONFIG_HFS_FS_POSIX_ACL is not set
 | |
| +# CONFIG_HI8435 is not set
 | |
| +# CONFIG_HIBERNATION is not set
 | |
| +# CONFIG_HID is not set
 | |
| +# CONFIG_HIDRAW is not set
 | |
| +# CONFIG_HID_A4TECH is not set
 | |
| +# CONFIG_HID_ACCUTOUCH is not set
 | |
| +# CONFIG_HID_ACRUX is not set
 | |
| +# CONFIG_HID_ACRUX_FF is not set
 | |
| +# CONFIG_HID_ALPS is not set
 | |
| +# CONFIG_HID_APPLE is not set
 | |
| +# CONFIG_HID_APPLEIR is not set
 | |
| +# CONFIG_HID_ASUS is not set
 | |
| +# CONFIG_HID_AUREAL is not set
 | |
| +# CONFIG_HID_BATTERY_STRENGTH is not set
 | |
| +# CONFIG_HID_BELKIN is not set
 | |
| +# CONFIG_HID_BETOP_FF is not set
 | |
| +# CONFIG_HID_BIGBEN_FF is not set
 | |
| +# CONFIG_HID_CHERRY is not set
 | |
| +# CONFIG_HID_CHICONY is not set
 | |
| +# CONFIG_HID_CMEDIA is not set
 | |
| +# CONFIG_HID_CORSAIR is not set
 | |
| +# CONFIG_HID_COUGAR is not set
 | |
| +# CONFIG_HID_CP2112 is not set
 | |
| +# CONFIG_HID_CREATIVE_SB0540 is not set
 | |
| +# CONFIG_HID_CYPRESS is not set
 | |
| +# CONFIG_HID_DRAGONRISE is not set
 | |
| +# CONFIG_HID_ELAN is not set
 | |
| +# CONFIG_HID_ELECOM is not set
 | |
| +# CONFIG_HID_ELO is not set
 | |
| +# CONFIG_HID_EMS_FF is not set
 | |
| +# CONFIG_HID_EZKEY is not set
 | |
| +# CONFIG_HID_GEMBIRD is not set
 | |
| +# CONFIG_HID_GENERIC is not set
 | |
| +# CONFIG_HID_GFRM is not set
 | |
| +# CONFIG_HID_GLORIOUS is not set
 | |
| +# CONFIG_HID_GOOGLE_HAMMER is not set
 | |
| +# CONFIG_HID_GREENASIA is not set
 | |
| +# CONFIG_HID_GT683R is not set
 | |
| +# CONFIG_HID_GYRATION is not set
 | |
| +# CONFIG_HID_HOLTEK is not set
 | |
| +# CONFIG_HID_ICADE is not set
 | |
| +# CONFIG_HID_ITE is not set
 | |
| +# CONFIG_HID_JABRA is not set
 | |
| +# CONFIG_HID_KENSINGTON is not set
 | |
| +# CONFIG_HID_KEYTOUCH is not set
 | |
| +# CONFIG_HID_KYE is not set
 | |
| +# CONFIG_HID_LCPOWER is not set
 | |
| +# CONFIG_HID_LED is not set
 | |
| +# CONFIG_HID_LENOVO is not set
 | |
| +# CONFIG_HID_LOGITECH is not set
 | |
| +# CONFIG_HID_LOGITECH_DJ is not set
 | |
| +# CONFIG_HID_LOGITECH_HIDPP is not set
 | |
| +# CONFIG_HID_MACALLY is not set
 | |
| +# CONFIG_HID_MAGICMOUSE is not set
 | |
| +# CONFIG_HID_MALTRON is not set
 | |
| +# CONFIG_HID_MAYFLASH is not set
 | |
| +# CONFIG_HID_MCP2221 is not set
 | |
| +# CONFIG_HID_MICROSOFT is not set
 | |
| +# CONFIG_HID_MONTEREY is not set
 | |
| +# CONFIG_HID_MULTITOUCH is not set
 | |
| +# CONFIG_HID_NTI is not set
 | |
| +# CONFIG_HID_NTRIG is not set
 | |
| +# CONFIG_HID_ORTEK is not set
 | |
| +# CONFIG_HID_PANTHERLORD is not set
 | |
| +# CONFIG_HID_PENMOUNT is not set
 | |
| +# CONFIG_HID_PETALYNX is not set
 | |
| +# CONFIG_HID_PICOLCD is not set
 | |
| +# CONFIG_HID_PID is not set
 | |
| +# CONFIG_HID_PLANTRONICS is not set
 | |
| +# CONFIG_HID_PRIMAX is not set
 | |
| +# CONFIG_HID_PRODIKEYS is not set
 | |
| +# CONFIG_HID_REDRAGON is not set
 | |
| +# CONFIG_HID_RETRODE is not set
 | |
| +# CONFIG_HID_RMI is not set
 | |
| +# CONFIG_HID_ROCCAT is not set
 | |
| +# CONFIG_HID_SAITEK is not set
 | |
| +# CONFIG_HID_SAMSUNG is not set
 | |
| +# CONFIG_HID_SENSOR_HUB is not set
 | |
| +# CONFIG_HID_SMARTJOYPLUS is not set
 | |
| +# CONFIG_HID_SONY is not set
 | |
| +# CONFIG_HID_SPEEDLINK is not set
 | |
| +# CONFIG_HID_STEAM is not set
 | |
| +# CONFIG_HID_STEELSERIES is not set
 | |
| +# CONFIG_HID_SUNPLUS is not set
 | |
| +# CONFIG_HID_THINGM is not set
 | |
| +# CONFIG_HID_THRUSTMASTER is not set
 | |
| +# CONFIG_HID_TIVO is not set
 | |
| +# CONFIG_HID_TOPSEED is not set
 | |
| +# CONFIG_HID_TWINHAN is not set
 | |
| +# CONFIG_HID_U2FZERO is not set
 | |
| +# CONFIG_HID_UCLOGIC is not set
 | |
| +# CONFIG_HID_UDRAW_PS3 is not set
 | |
| +# CONFIG_HID_VIEWSONIC is not set
 | |
| +# CONFIG_HID_VIVALDI is not set
 | |
| +# CONFIG_HID_WACOM is not set
 | |
| +# CONFIG_HID_WALTOP is not set
 | |
| +# CONFIG_HID_WIIMOTE is not set
 | |
| +# CONFIG_HID_XINMO is not set
 | |
| +# CONFIG_HID_ZEROPLUS is not set
 | |
| +# CONFIG_HID_ZYDACRON is not set
 | |
| +# CONFIG_HIGHMEM is not set
 | |
| +CONFIG_HIGH_RES_TIMERS=y
 | |
| +# CONFIG_HINIC is not set
 | |
| +# CONFIG_HIP04_ETH is not set
 | |
| +# CONFIG_HIPPI is not set
 | |
| +# CONFIG_HISILICON_ERRATUM_161010101 is not set
 | |
| +# CONFIG_HISILICON_ERRATUM_161600802 is not set
 | |
| +# CONFIG_HISI_DMA is not set
 | |
| +# CONFIG_HISI_FEMAC is not set
 | |
| +# CONFIG_HISI_HIKEY_USB is not set
 | |
| +# CONFIG_HIX5HD2_GMAC is not set
 | |
| +# CONFIG_HMC425 is not set
 | |
| +# CONFIG_HMC6352 is not set
 | |
| +# CONFIG_HNS is not set
 | |
| +# CONFIG_HNS3 is not set
 | |
| +# CONFIG_HNS_DSAF is not set
 | |
| +# CONFIG_HNS_ENET is not set
 | |
| +# CONFIG_HOSTAP is not set
 | |
| +# CONFIG_HOSTAP_CS is not set
 | |
| +# CONFIG_HOSTAP_PCI is not set
 | |
| +# CONFIG_HOSTAP_PLX is not set
 | |
| +# CONFIG_HOTPLUG_CPU is not set
 | |
| +# CONFIG_HOTPLUG_PCI is not set
 | |
| +# CONFIG_HP03 is not set
 | |
| +# CONFIG_HP100 is not set
 | |
| +# CONFIG_HP206C is not set
 | |
| +CONFIG_HPET_MMAP_DEFAULT=y
 | |
| +# CONFIG_HPFS_FS is not set
 | |
| +# CONFIG_HP_ILO is not set
 | |
| +# CONFIG_HP_WIRELESS is not set
 | |
| +# CONFIG_HSA_AMD is not set
 | |
| +# CONFIG_HSI is not set
 | |
| +# CONFIG_HSR is not set
 | |
| +# CONFIG_HTC_EGPIO is not set
 | |
| +# CONFIG_HTC_I2CPLD is not set
 | |
| +# CONFIG_HTC_PASIC3 is not set
 | |
| +# CONFIG_HTS221 is not set
 | |
| +# CONFIG_HTU21 is not set
 | |
| +# CONFIG_HUGETLBFS is not set
 | |
| +# CONFIG_HUGETLB_PAGE is not set
 | |
| +# CONFIG_HVC_DCC is not set
 | |
| +# CONFIG_HVC_UDBG is not set
 | |
| +# CONFIG_HWLAT_TRACER is not set
 | |
| +# CONFIG_HWMON is not set
 | |
| +# CONFIG_HWMON_DEBUG_CHIP is not set
 | |
| +# CONFIG_HWMON_VID is not set
 | |
| +# CONFIG_HWSPINLOCK is not set
 | |
| +# CONFIG_HWSPINLOCK_OMAP is not set
 | |
| +CONFIG_HW_PERF_EVENTS=y
 | |
| +# CONFIG_HW_RANDOM is not set
 | |
| +# CONFIG_HW_RANDOM_AMD is not set
 | |
| +# CONFIG_HW_RANDOM_ATMEL is not set
 | |
| +# CONFIG_HW_RANDOM_BA431 is not set
 | |
| +# CONFIG_HW_RANDOM_CAVIUM is not set
 | |
| +# CONFIG_HW_RANDOM_CCTRNG is not set
 | |
| +# CONFIG_HW_RANDOM_EXYNOS is not set
 | |
| +# CONFIG_HW_RANDOM_GEODE is not set
 | |
| +# CONFIG_HW_RANDOM_INTEL is not set
 | |
| +# CONFIG_HW_RANDOM_IPROC_RNG200 is not set
 | |
| +# CONFIG_HW_RANDOM_MTK is not set
 | |
| +# CONFIG_HW_RANDOM_OMAP is not set
 | |
| +# CONFIG_HW_RANDOM_OMAP3_ROM is not set
 | |
| +# CONFIG_HW_RANDOM_PPC4XX is not set
 | |
| +# CONFIG_HW_RANDOM_TIMERIOMEM is not set
 | |
| +CONFIG_HW_RANDOM_TPM=y
 | |
| +# CONFIG_HW_RANDOM_VIA is not set
 | |
| +# CONFIG_HW_RANDOM_VIRTIO is not set
 | |
| +# CONFIG_HW_RANDOM_XIPHERA is not set
 | |
| +# CONFIG_HX711 is not set
 | |
| +# CONFIG_HYPERV is not set
 | |
| +# CONFIG_HYPERV_TSCPAGE is not set
 | |
| +# CONFIG_HYSDN is not set
 | |
| +# CONFIG_HZ is not set
 | |
| +# CONFIG_HZ_100 is not set
 | |
| +# CONFIG_HZ_1000 is not set
 | |
| +# CONFIG_HZ_1024 is not set
 | |
| +# CONFIG_HZ_128 is not set
 | |
| +# CONFIG_HZ_200 is not set
 | |
| +# CONFIG_HZ_24 is not set
 | |
| +# CONFIG_HZ_250 is not set
 | |
| +# CONFIG_HZ_256 is not set
 | |
| +# CONFIG_HZ_300 is not set
 | |
| +# CONFIG_HZ_48 is not set
 | |
| +# CONFIG_HZ_500 is not set
 | |
| +# CONFIG_HZ_PERIODIC is not set
 | |
| +# CONFIG_I2C is not set
 | |
| +# CONFIG_I2C_ALGOBIT is not set
 | |
| +# CONFIG_I2C_ALGOPCA is not set
 | |
| +# CONFIG_I2C_ALGOPCF is not set
 | |
| +# CONFIG_I2C_ALI1535 is not set
 | |
| +# CONFIG_I2C_ALI1563 is not set
 | |
| +# CONFIG_I2C_ALI15X3 is not set
 | |
| +# CONFIG_I2C_AMD756 is not set
 | |
| +# CONFIG_I2C_AMD8111 is not set
 | |
| +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
 | |
| +# CONFIG_I2C_AU1550 is not set
 | |
| +# CONFIG_I2C_BCM2835 is not set
 | |
| +# CONFIG_I2C_BCM_IPROC is not set
 | |
| +# CONFIG_I2C_CADENCE is not set
 | |
| +# CONFIG_I2C_CBUS_GPIO is not set
 | |
| +# CONFIG_I2C_CHARDEV is not set
 | |
| +# CONFIG_I2C_COMPAT is not set
 | |
| +# CONFIG_I2C_DEBUG_ALGO is not set
 | |
| +# CONFIG_I2C_DEBUG_BUS is not set
 | |
| +# CONFIG_I2C_DEBUG_CORE is not set
 | |
| +# CONFIG_I2C_DEMUX_PINCTRL is not set
 | |
| +# CONFIG_I2C_DESIGNWARE_PCI is not set
 | |
| +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
 | |
| +# CONFIG_I2C_DIOLAN_U2C is not set
 | |
| +# CONFIG_I2C_EG20T is not set
 | |
| +# CONFIG_I2C_ELEKTOR is not set
 | |
| +# CONFIG_I2C_EMEV2 is not set
 | |
| +# CONFIG_I2C_GPIO is not set
 | |
| +# CONFIG_I2C_GPIO_FAULT_INJECTOR is not set
 | |
| +# CONFIG_I2C_HELPER_AUTO is not set
 | |
| +# CONFIG_I2C_HID is not set
 | |
| +# CONFIG_I2C_I801 is not set
 | |
| +# CONFIG_I2C_IBM_IIC is not set
 | |
| +# CONFIG_I2C_IMG is not set
 | |
| +# CONFIG_I2C_ISCH is not set
 | |
| +# CONFIG_I2C_ISMT is not set
 | |
| +# CONFIG_I2C_JZ4780 is not set
 | |
| +# CONFIG_I2C_MLXCPLD is not set
 | |
| +# CONFIG_I2C_MPC is not set
 | |
| +# CONFIG_I2C_MT65XX is not set
 | |
| +# CONFIG_I2C_MUX is not set
 | |
| +# CONFIG_I2C_MUX_GPIO is not set
 | |
| +# CONFIG_I2C_MUX_GPMUX is not set
 | |
| +# CONFIG_I2C_MUX_LTC4306 is not set
 | |
| +# CONFIG_I2C_MUX_MLXCPLD is not set
 | |
| +# CONFIG_I2C_MUX_PCA9541 is not set
 | |
| +# CONFIG_I2C_MUX_PCA954x is not set
 | |
| +# CONFIG_I2C_MUX_PINCTRL is not set
 | |
| +# CONFIG_I2C_MUX_REG is not set
 | |
| +# CONFIG_I2C_MV64XXX is not set
 | |
| +# CONFIG_I2C_NFORCE2 is not set
 | |
| +# CONFIG_I2C_NOMADIK is not set
 | |
| +# CONFIG_I2C_NVIDIA_GPU is not set
 | |
| +# CONFIG_I2C_OCORES is not set
 | |
| +# CONFIG_I2C_OCTEON is not set
 | |
| +# CONFIG_I2C_PARPORT is not set
 | |
| +# CONFIG_I2C_PARPORT_LIGHT is not set
 | |
| +# CONFIG_I2C_PCA_ISA is not set
 | |
| +# CONFIG_I2C_PCA_PLATFORM is not set
 | |
| +# CONFIG_I2C_PIIX4 is not set
 | |
| +# CONFIG_I2C_PXA_PCI is not set
 | |
| +# CONFIG_I2C_PXA_SLAVE is not set
 | |
| +# CONFIG_I2C_RCAR is not set
 | |
| +# CONFIG_I2C_RK3X is not set
 | |
| +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
 | |
| +# CONFIG_I2C_S3C2410 is not set
 | |
| +# CONFIG_I2C_SCMI is not set
 | |
| +# CONFIG_I2C_SH_MOBILE is not set
 | |
| +# CONFIG_I2C_SIMTEC is not set
 | |
| +# CONFIG_I2C_SIS5595 is not set
 | |
| +# CONFIG_I2C_SIS630 is not set
 | |
| +# CONFIG_I2C_SIS96X is not set
 | |
| +# CONFIG_I2C_SLAVE is not set
 | |
| +# CONFIG_I2C_SLAVE_EEPROM is not set
 | |
| +# CONFIG_I2C_SMBUS is not set
 | |
| +# CONFIG_I2C_STUB is not set
 | |
| +# CONFIG_I2C_TAOS_EVM is not set
 | |
| +# CONFIG_I2C_THUNDERX is not set
 | |
| +# CONFIG_I2C_TINY_USB is not set
 | |
| +# CONFIG_I2C_VERSATILE is not set
 | |
| +# CONFIG_I2C_VIA is not set
 | |
| +# CONFIG_I2C_VIAPRO is not set
 | |
| +# CONFIG_I2C_XILINX is not set
 | |
| +# CONFIG_I3C is not set
 | |
| +# CONFIG_I40E is not set
 | |
| +# CONFIG_I40EVF is not set
 | |
| +# CONFIG_I6300ESB_WDT is not set
 | |
| +# CONFIG_I82092 is not set
 | |
| +# CONFIG_I82365 is not set
 | |
| +# CONFIG_IAQCORE is not set
 | |
| +# CONFIG_IBM_ASM is not set
 | |
| +# CONFIG_IBM_EMAC_DEBUG is not set
 | |
| +# CONFIG_IBM_EMAC_EMAC4 is not set
 | |
| +# CONFIG_IBM_EMAC_MAL_CLR_ICINTSTAT is not set
 | |
| +# CONFIG_IBM_EMAC_MAL_COMMON_ERR is not set
 | |
| +# CONFIG_IBM_EMAC_NO_FLOW_CTRL is not set
 | |
| +# CONFIG_IBM_EMAC_RGMII is not set
 | |
| +# CONFIG_IBM_EMAC_TAH is not set
 | |
| +# CONFIG_IBM_EMAC_ZMII is not set
 | |
| +# CONFIG_ICE is not set
 | |
| +# CONFIG_ICP10100 is not set
 | |
| +# CONFIG_ICPLUS_PHY is not set
 | |
| +# CONFIG_ICS932S401 is not set
 | |
| +# CONFIG_IDE is not set
 | |
| +# CONFIG_IDEAPAD_LAPTOP is not set
 | |
| +# CONFIG_IDE_GD is not set
 | |
| +# CONFIG_IDE_PROC_FS is not set
 | |
| +# CONFIG_IDE_TASK_IOCTL is not set
 | |
| +# CONFIG_IDLE_PAGE_TRACKING is not set
 | |
| +# CONFIG_IEEE802154 is not set
 | |
| +# CONFIG_IEEE802154_ADF7242 is not set
 | |
| +# CONFIG_IEEE802154_ATUSB is not set
 | |
| +# CONFIG_IEEE802154_CA8210 is not set
 | |
| +# CONFIG_IEEE802154_HWSIM is not set
 | |
| +# CONFIG_IEEE802154_MCR20A is not set
 | |
| +# CONFIG_IFB is not set
 | |
| +# CONFIG_IGB is not set
 | |
| +# CONFIG_IGBVF is not set
 | |
| +# CONFIG_IGC is not set
 | |
| +# CONFIG_IIO is not set
 | |
| +# CONFIG_IIO_BUFFER is not set
 | |
| +# CONFIG_IIO_BUFFER_CB is not set
 | |
| +# CONFIG_IIO_BUFFER_DMA is not set
 | |
| +# CONFIG_IIO_BUFFER_DMAENGINE is not set
 | |
| +# CONFIG_IIO_BUFFER_HDC2010 is not set
 | |
| +# CONFIG_IIO_BUFFER_HW_CONSUMER is not set
 | |
| +# CONFIG_IIO_CONFIGFS is not set
 | |
| +CONFIG_IIO_CONSUMERS_PER_TRIGGER=2
 | |
| +# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set
 | |
| +# CONFIG_IIO_INTERRUPT_TRIGGER is not set
 | |
| +# CONFIG_IIO_MUX is not set
 | |
| +# CONFIG_IIO_PERIODIC_RTC_TRIGGER is not set
 | |
| +# CONFIG_IIO_RESCALE is not set
 | |
| +# CONFIG_IIO_SIMPLE_DUMMY is not set
 | |
| +# CONFIG_IIO_SSP_SENSORHUB is not set
 | |
| +# CONFIG_IIO_ST_ACCEL_3AXIS is not set
 | |
| +# CONFIG_IIO_ST_GYRO_3AXIS is not set
 | |
| +# CONFIG_IIO_ST_LSM6DSX is not set
 | |
| +# CONFIG_IIO_ST_MAGN_3AXIS is not set
 | |
| +# CONFIG_IIO_ST_PRESS is not set
 | |
| +# CONFIG_IIO_SW_DEVICE is not set
 | |
| +# CONFIG_IIO_SW_TRIGGER is not set
 | |
| +# CONFIG_IIO_SYSFS_TRIGGER is not set
 | |
| +# CONFIG_IIO_TRIGGER is not set
 | |
| +# CONFIG_IIO_TRIGGERED_EVENT is not set
 | |
| +# CONFIG_IKCONFIG is not set
 | |
| +# CONFIG_IKCONFIG_PROC is not set
 | |
| +# CONFIG_IKHEADERS is not set
 | |
| +# CONFIG_IMA is not set
 | |
| +# CONFIG_IMAGE_CMDLINE_HACK is not set
 | |
| +# CONFIG_IMGPDC_WDT is not set
 | |
| +# CONFIG_IMG_MDC_DMA is not set
 | |
| +# CONFIG_IMX7D_ADC is not set
 | |
| +# CONFIG_IMX_IPUV3_CORE is not set
 | |
| +# CONFIG_IMX_THERMAL is not set
 | |
| +# CONFIG_INA2XX_ADC is not set
 | |
| +# CONFIG_INDIRECT_PIO is not set
 | |
| +CONFIG_INET=y
 | |
| +# CONFIG_INET6_AH is not set
 | |
| +# CONFIG_INET6_ESP is not set
 | |
| +# CONFIG_INET6_ESPINTCP is not set
 | |
| +# CONFIG_INET6_IPCOMP is not set
 | |
| +# CONFIG_INET6_TUNNEL is not set
 | |
| +# CONFIG_INET6_XFRM_MODE_BEET is not set
 | |
| +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
 | |
| +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
 | |
| +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
 | |
| +# CONFIG_INET6_XFRM_TUNNEL is not set
 | |
| +# CONFIG_INET_AH is not set
 | |
| +# CONFIG_INET_DIAG is not set
 | |
| +# CONFIG_INET_ESP is not set
 | |
| +# CONFIG_INET_ESPINTCP is not set
 | |
| +# CONFIG_INET_IPCOMP is not set
 | |
| +# CONFIG_INET_LRO is not set
 | |
| +# CONFIG_INET_TCP_DIAG is not set
 | |
| +# CONFIG_INET_TUNNEL is not set
 | |
| +# CONFIG_INET_UDP_DIAG is not set
 | |
| +# CONFIG_INET_XFRM_MODE_BEET is not set
 | |
| +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
 | |
| +# CONFIG_INET_XFRM_MODE_TUNNEL is not set
 | |
| +# CONFIG_INET_XFRM_TUNNEL is not set
 | |
| +# CONFIG_INFINIBAND is not set
 | |
| +# CONFIG_INFTL is not set
 | |
| +# CONFIG_INGENIC_ADC is not set
 | |
| +# CONFIG_INGENIC_CGU_JZ4725B is not set
 | |
| +# CONFIG_INGENIC_CGU_JZ4740 is not set
 | |
| +# CONFIG_INGENIC_CGU_JZ4770 is not set
 | |
| +# CONFIG_INGENIC_CGU_JZ4780 is not set
 | |
| +# CONFIG_INGENIC_CGU_X1000 is not set
 | |
| +# CONFIG_INGENIC_CGU_X1830 is not set
 | |
| +# CONFIG_INGENIC_OST is not set
 | |
| +# CONFIG_INGENIC_SYSOST is not set
 | |
| +# CONFIG_INGENIC_TCU_CLK is not set
 | |
| +# CONFIG_INGENIC_TCU_IRQ is not set
 | |
| +# CONFIG_INGENIC_TIMER is not set
 | |
| +CONFIG_INIT_ENV_ARG_LIMIT=32
 | |
| +# CONFIG_INIT_ON_ALLOC_DEFAULT_ON is not set
 | |
| +# CONFIG_INIT_ON_FREE_DEFAULT_ON is not set
 | |
| +CONFIG_INIT_STACK_NONE=y
 | |
| +CONFIG_INOTIFY_USER=y
 | |
| +# CONFIG_INPUT is not set
 | |
| +# CONFIG_INPUT_AD714X is not set
 | |
| +# CONFIG_INPUT_ADXL34X is not set
 | |
| +# CONFIG_INPUT_APANEL is not set
 | |
| +# CONFIG_INPUT_ATI_REMOTE2 is not set
 | |
| +# CONFIG_INPUT_ATLAS_BTNS is not set
 | |
| +# CONFIG_INPUT_ATMEL_CAPTOUCH is not set
 | |
| +# CONFIG_INPUT_AXP20X_PEK is not set
 | |
| +# CONFIG_INPUT_BMA150 is not set
 | |
| +# CONFIG_INPUT_CM109 is not set
 | |
| +# CONFIG_INPUT_CMA3000 is not set
 | |
| +# CONFIG_INPUT_DRV260X_HAPTICS is not set
 | |
| +# CONFIG_INPUT_DRV2665_HAPTICS is not set
 | |
| +# CONFIG_INPUT_DRV2667_HAPTICS is not set
 | |
| +# CONFIG_INPUT_E3X0_BUTTON is not set
 | |
| +# CONFIG_INPUT_EVBUG is not set
 | |
| +# CONFIG_INPUT_EVDEV is not set
 | |
| +# CONFIG_INPUT_FF_MEMLESS is not set
 | |
| +# CONFIG_INPUT_GP2A is not set
 | |
| +# CONFIG_INPUT_GPIO_BEEPER is not set
 | |
| +# CONFIG_INPUT_GPIO_DECODER is not set
 | |
| +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
 | |
| +# CONFIG_INPUT_GPIO_TILT_POLLED is not set
 | |
| +# CONFIG_INPUT_GPIO_VIBRA is not set
 | |
| +# CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set
 | |
| +# CONFIG_INPUT_IMS_PCU is not set
 | |
| +# CONFIG_INPUT_IQS269A is not set
 | |
| +# CONFIG_INPUT_JOYDEV is not set
 | |
| +# CONFIG_INPUT_JOYSTICK is not set
 | |
| +# CONFIG_INPUT_KEYBOARD is not set
 | |
| +# CONFIG_INPUT_KEYSPAN_REMOTE is not set
 | |
| +# CONFIG_INPUT_KXTJ9 is not set
 | |
| +# CONFIG_INPUT_LEDS is not set
 | |
| +# CONFIG_INPUT_MATRIXKMAP is not set
 | |
| +# CONFIG_INPUT_MAX8997_HAPTIC is not set
 | |
| +CONFIG_INPUT_MISC=y
 | |
| +# CONFIG_INPUT_MMA8450 is not set
 | |
| +# CONFIG_INPUT_MOUSE is not set
 | |
| +# CONFIG_INPUT_MOUSEDEV is not set
 | |
| +# CONFIG_INPUT_MPU3050 is not set
 | |
| +# CONFIG_INPUT_MSM_VIBRATOR is not set
 | |
| +# CONFIG_INPUT_PALMAS_PWRBUTTON is not set
 | |
| +# CONFIG_INPUT_PCF8574 is not set
 | |
| +# CONFIG_INPUT_PCSPKR is not set
 | |
| +# CONFIG_INPUT_POLLDEV is not set
 | |
| +# CONFIG_INPUT_POWERMATE is not set
 | |
| +# CONFIG_INPUT_PWM_BEEPER is not set
 | |
| +# CONFIG_INPUT_PWM_VIBRA is not set
 | |
| +# CONFIG_INPUT_REGULATOR_HAPTIC is not set
 | |
| +# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set
 | |
| +# CONFIG_INPUT_SPARSEKMAP is not set
 | |
| +# CONFIG_INPUT_TABLET is not set
 | |
| +# CONFIG_INPUT_TOUCHSCREEN is not set
 | |
| +# CONFIG_INPUT_TPS65218_PWRBUTTON is not set
 | |
| +# CONFIG_INPUT_TWL4030_PWRBUTTON is not set
 | |
| +# CONFIG_INPUT_TWL4030_VIBRA is not set
 | |
| +# CONFIG_INPUT_TWL6040_VIBRA is not set
 | |
| +# CONFIG_INPUT_UINPUT is not set
 | |
| +# CONFIG_INPUT_WISTRON_BTNS is not set
 | |
| +# CONFIG_INPUT_YEALINK is not set
 | |
| +# CONFIG_INT340X_THERMAL is not set
 | |
| +# CONFIG_INTEGRITY is not set
 | |
| +# CONFIG_INTEGRITY_AUDIT is not set
 | |
| +# CONFIG_INTEGRITY_SIGNATURE is not set
 | |
| +# CONFIG_INTEL_ATOMISP2_LED is not set
 | |
| +# CONFIG_INTEL_ATOMISP2_PM is not set
 | |
| +# CONFIG_INTEL_CHT_INT33FE is not set
 | |
| +# CONFIG_INTEL_HID_EVENT is not set
 | |
| +# CONFIG_INTEL_IDLE is not set
 | |
| +# CONFIG_INTEL_IDMA64 is not set
 | |
| +# CONFIG_INTEL_INT0002_VGPIO is not set
 | |
| +# CONFIG_INTEL_IOATDMA is not set
 | |
| +# CONFIG_INTEL_ISH_HID is not set
 | |
| +# CONFIG_INTEL_MEI is not set
 | |
| +# CONFIG_INTEL_MEI_ME is not set
 | |
| +# CONFIG_INTEL_MEI_TXE is not set
 | |
| +# CONFIG_INTEL_MIC_CARD is not set
 | |
| +# CONFIG_INTEL_MIC_HOST is not set
 | |
| +# CONFIG_INTEL_MID_PTI is not set
 | |
| +# CONFIG_INTEL_OAKTRAIL is not set
 | |
| +# CONFIG_INTEL_PMC_CORE is not set
 | |
| +# CONFIG_INTEL_PUNIT_IPC is not set
 | |
| +# CONFIG_INTEL_RST is not set
 | |
| +# CONFIG_INTEL_SMARTCONNECT is not set
 | |
| +# CONFIG_INTEL_SOC_PMIC is not set
 | |
| +# CONFIG_INTEL_SOC_PMIC_CHTDC_TI is not set
 | |
| +# CONFIG_INTEL_SOC_PMIC_CHTWC is not set
 | |
| +# CONFIG_INTEL_TH is not set
 | |
| +# CONFIG_INTEL_VBTN is not set
 | |
| +# CONFIG_INTEL_XWAY_PHY is not set
 | |
| +# CONFIG_INTERCONNECT is not set
 | |
| +# CONFIG_INTERVAL_TREE_TEST is not set
 | |
| +# CONFIG_INV_ICM42600_I2C is not set
 | |
| +# CONFIG_INV_ICM42600_SPI is not set
 | |
| +# CONFIG_INV_MPU6050_I2C is not set
 | |
| +# CONFIG_INV_MPU6050_IIO is not set
 | |
| +# CONFIG_INV_MPU6050_SPI is not set
 | |
| +# CONFIG_IOMMU_SUPPORT is not set
 | |
| +# CONFIG_IONIC is not set
 | |
| +# CONFIG_IOSCHED_BFQ is not set
 | |
| +# CONFIG_IOSCHED_CFQ is not set
 | |
| +CONFIG_IOSCHED_DEADLINE=y
 | |
| +CONFIG_IOSCHED_NOOP=y
 | |
| +CONFIG_IO_STRICT_DEVMEM=y
 | |
| +# CONFIG_IO_URING is not set
 | |
| +CONFIG_IO_WQ=y
 | |
| +# CONFIG_IP17XX_PHY is not set
 | |
| +# CONFIG_IP6_NF_FILTER is not set
 | |
| +# CONFIG_IP6_NF_IPTABLES is not set
 | |
| +# CONFIG_IP6_NF_MANGLE is not set
 | |
| +# CONFIG_IP6_NF_MATCH_AH is not set
 | |
| +# CONFIG_IP6_NF_MATCH_EUI64 is not set
 | |
| +# CONFIG_IP6_NF_MATCH_FRAG is not set
 | |
| +# CONFIG_IP6_NF_MATCH_HL is not set
 | |
| +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
 | |
| +# CONFIG_IP6_NF_MATCH_MH is not set
 | |
| +# CONFIG_IP6_NF_MATCH_OPTS is not set
 | |
| +# CONFIG_IP6_NF_MATCH_RPFILTER is not set
 | |
| +# CONFIG_IP6_NF_MATCH_RT is not set
 | |
| +# CONFIG_IP6_NF_MATCH_SRH is not set
 | |
| +# CONFIG_IP6_NF_NAT is not set
 | |
| +# CONFIG_IP6_NF_RAW is not set
 | |
| +# CONFIG_IP6_NF_SECURITY is not set
 | |
| +# CONFIG_IP6_NF_TARGET_HL is not set
 | |
| +# CONFIG_IP6_NF_TARGET_MASQUERADE is not set
 | |
| +# CONFIG_IP6_NF_TARGET_REJECT is not set
 | |
| +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set
 | |
| +# CONFIG_IPACK_BUS is not set
 | |
| +# CONFIG_IPC_NS is not set
 | |
| +# CONFIG_IPMB_DEVICE_INTERFACE is not set
 | |
| +# CONFIG_IPMI_HANDLER is not set
 | |
| +# CONFIG_IPV6 is not set
 | |
| +# CONFIG_IPV6_FOU is not set
 | |
| +# CONFIG_IPV6_FOU_TUNNEL is not set
 | |
| +# CONFIG_IPV6_ILA is not set
 | |
| +# CONFIG_IPV6_MIP6 is not set
 | |
| +# CONFIG_IPV6_MROUTE is not set
 | |
| +# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
 | |
| +# CONFIG_IPV6_MULTIPLE_TABLES is not set
 | |
| +CONFIG_IPV6_NDISC_NODETYPE=y
 | |
| +# CONFIG_IPV6_OPTIMISTIC_DAD is not set
 | |
| +# CONFIG_IPV6_ROUTER_PREF is not set
 | |
| +# CONFIG_IPV6_ROUTE_INFO is not set
 | |
| +# CONFIG_IPV6_RPL_LWTUNNEL is not set
 | |
| +# CONFIG_IPV6_SEG6_HMAC is not set
 | |
| +# CONFIG_IPV6_SEG6_LWTUNNEL is not set
 | |
| +# CONFIG_IPV6_SIT is not set
 | |
| +# CONFIG_IPV6_SIT_6RD is not set
 | |
| +# CONFIG_IPV6_TUNNEL is not set
 | |
| +# CONFIG_IPV6_VTI is not set
 | |
| +# CONFIG_IPVLAN is not set
 | |
| +# CONFIG_IPW2100 is not set
 | |
| +# CONFIG_IPW2100_DEBUG is not set
 | |
| +CONFIG_IPW2100_MONITOR=y
 | |
| +# CONFIG_IPW2200 is not set
 | |
| +# CONFIG_IPW2200_DEBUG is not set
 | |
| +CONFIG_IPW2200_MONITOR=y
 | |
| +# CONFIG_IPW2200_PROMISCUOUS is not set
 | |
| +# CONFIG_IPW2200_QOS is not set
 | |
| +# CONFIG_IPW2200_RADIOTAP is not set
 | |
| +# CONFIG_IPWIRELESS is not set
 | |
| +# CONFIG_IPX is not set
 | |
| +CONFIG_IP_ADVANCED_ROUTER=y
 | |
| +# CONFIG_IP_DCCP is not set
 | |
| +# CONFIG_IP_FIB_TRIE_STATS is not set
 | |
| +# CONFIG_IP_MROUTE is not set
 | |
| +CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
 | |
| +CONFIG_IP_MULTICAST=y
 | |
| +CONFIG_IP_MULTIPLE_TABLES=y
 | |
| +# CONFIG_IP_NF_ARPFILTER is not set
 | |
| +# CONFIG_IP_NF_ARPTABLES is not set
 | |
| +# CONFIG_IP_NF_ARP_MANGLE is not set
 | |
| +# CONFIG_IP_NF_FILTER is not set
 | |
| +# CONFIG_IP_NF_IPTABLES is not set
 | |
| +# CONFIG_IP_NF_MANGLE is not set
 | |
| +# CONFIG_IP_NF_MATCH_AH is not set
 | |
| +# CONFIG_IP_NF_MATCH_ECN is not set
 | |
| +# CONFIG_IP_NF_MATCH_RPFILTER is not set
 | |
| +# CONFIG_IP_NF_MATCH_TTL is not set
 | |
| +# CONFIG_IP_NF_RAW is not set
 | |
| +# CONFIG_IP_NF_SECURITY is not set
 | |
| +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
 | |
| +# CONFIG_IP_NF_TARGET_ECN is not set
 | |
| +# CONFIG_IP_NF_TARGET_MASQUERADE is not set
 | |
| +# CONFIG_IP_NF_TARGET_NETMAP is not set
 | |
| +# CONFIG_IP_NF_TARGET_REDIRECT is not set
 | |
| +# CONFIG_IP_NF_TARGET_REJECT is not set
 | |
| +# CONFIG_IP_NF_TARGET_SYNPROXY is not set
 | |
| +# CONFIG_IP_NF_TARGET_TTL is not set
 | |
| +# CONFIG_IP_PIMSM_V1 is not set
 | |
| +# CONFIG_IP_PIMSM_V2 is not set
 | |
| +# CONFIG_IP_PNP is not set
 | |
| +CONFIG_IP_ROUTE_MULTIPATH=y
 | |
| +CONFIG_IP_ROUTE_VERBOSE=y
 | |
| +# CONFIG_IP_SCTP is not set
 | |
| +# CONFIG_IP_SET is not set
 | |
| +# CONFIG_IP_SET_HASH_IPMAC is not set
 | |
| +# CONFIG_IP_VS is not set
 | |
| +# CONFIG_IP_VS_MH is not set
 | |
| +CONFIG_IP_VS_MH_TAB_INDEX=10
 | |
| +# CONFIG_IRDA is not set
 | |
| +# CONFIG_IRQSOFF_TRACER is not set
 | |
| +# CONFIG_IRQ_ALL_CPUS is not set
 | |
| +# CONFIG_IRQ_DOMAIN_DEBUG is not set
 | |
| +# CONFIG_IRQ_POLL is not set
 | |
| +# CONFIG_IRQ_TIME_ACCOUNTING is not set
 | |
| +# CONFIG_IR_GPIO_CIR is not set
 | |
| +# CONFIG_IR_HIX5HD2 is not set
 | |
| +# CONFIG_IR_IGORPLUGUSB is not set
 | |
| +# CONFIG_IR_IGUANA is not set
 | |
| +# CONFIG_IR_IMG is not set
 | |
| +# CONFIG_IR_IMON is not set
 | |
| +# CONFIG_IR_JVC_DECODER is not set
 | |
| +# CONFIG_IR_LIRC_CODEC is not set
 | |
| +# CONFIG_IR_MCEUSB is not set
 | |
| +# CONFIG_IR_NEC_DECODER is not set
 | |
| +# CONFIG_IR_RC5_DECODER is not set
 | |
| +# CONFIG_IR_RC6_DECODER is not set
 | |
| +# CONFIG_IR_REDRAT3 is not set
 | |
| +# CONFIG_IR_SONY_DECODER is not set
 | |
| +# CONFIG_IR_STREAMZAP is not set
 | |
| +# CONFIG_IR_TTUSBIR is not set
 | |
| +# CONFIG_ISA_BUS is not set
 | |
| +# CONFIG_ISA_BUS_API is not set
 | |
| +# CONFIG_ISCSI_BOOT_SYSFS is not set
 | |
| +# CONFIG_ISCSI_TCP is not set
 | |
| +CONFIG_ISDN=y
 | |
| +# CONFIG_ISDN_AUDIO is not set
 | |
| +# CONFIG_ISDN_CAPI is not set
 | |
| +# CONFIG_ISDN_CAPI_CAPIDRV is not set
 | |
| +# CONFIG_ISDN_DIVERSION is not set
 | |
| +# CONFIG_ISDN_DRV_ACT2000 is not set
 | |
| +# CONFIG_ISDN_DRV_GIGASET is not set
 | |
| +# CONFIG_ISDN_DRV_HISAX is not set
 | |
| +# CONFIG_ISDN_DRV_ICN is not set
 | |
| +# CONFIG_ISDN_DRV_LOOP is not set
 | |
| +# CONFIG_ISDN_DRV_PCBIT is not set
 | |
| +# CONFIG_ISDN_DRV_SC is not set
 | |
| +# CONFIG_ISDN_I4L is not set
 | |
| +# CONFIG_ISL29003 is not set
 | |
| +# CONFIG_ISL29020 is not set
 | |
| +# CONFIG_ISL29125 is not set
 | |
| +# CONFIG_ISL29501 is not set
 | |
| +# CONFIG_ISO9660_FS is not set
 | |
| +# CONFIG_ISS4xx is not set
 | |
| +# CONFIG_ITG3200 is not set
 | |
| +# CONFIG_IWL3945 is not set
 | |
| +# CONFIG_IWLWIFI is not set
 | |
| +# CONFIG_IXGB is not set
 | |
| +# CONFIG_IXGBE is not set
 | |
| +# CONFIG_IXGBEVF is not set
 | |
| +# CONFIG_JAILHOUSE_GUEST is not set
 | |
| +# CONFIG_JBD2_DEBUG is not set
 | |
| +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
 | |
| +# CONFIG_JFFS2_CMODE_NONE is not set
 | |
| +CONFIG_JFFS2_CMODE_PRIORITY=y
 | |
| +# CONFIG_JFFS2_CMODE_SIZE is not set
 | |
| +CONFIG_JFFS2_COMPRESSION_OPTIONS=y
 | |
| +CONFIG_JFFS2_FS=y
 | |
| +CONFIG_JFFS2_FS_DEBUG=0
 | |
| +# CONFIG_JFFS2_FS_POSIX_ACL is not set
 | |
| +# CONFIG_JFFS2_FS_SECURITY is not set
 | |
| +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 | |
| +CONFIG_JFFS2_FS_WRITEBUFFER=y
 | |
| +CONFIG_JFFS2_FS_XATTR=y
 | |
| +CONFIG_JFFS2_LZMA=y
 | |
| +# CONFIG_JFFS2_LZO is not set
 | |
| +CONFIG_JFFS2_RTIME=y
 | |
| +# CONFIG_JFFS2_RUBIN is not set
 | |
| +CONFIG_JFFS2_SUMMARY=y
 | |
| +# CONFIG_JFFS2_ZLIB is not set
 | |
| +# CONFIG_JFS_DEBUG is not set
 | |
| +# CONFIG_JFS_FS is not set
 | |
| +# CONFIG_JFS_POSIX_ACL is not set
 | |
| +# CONFIG_JFS_SECURITY is not set
 | |
| +# CONFIG_JFS_STATISTICS is not set
 | |
| +# CONFIG_JME is not set
 | |
| +CONFIG_JOLIET=y
 | |
| +# CONFIG_JSA1212 is not set
 | |
| +# CONFIG_JUMP_LABEL is not set
 | |
| +# CONFIG_JZ4740_WDT is not set
 | |
| +# CONFIG_JZ4770_PHY is not set
 | |
| +# CONFIG_KALLSYMS is not set
 | |
| +# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set
 | |
| +# CONFIG_KALLSYMS_ALL is not set
 | |
| +CONFIG_KALLSYMS_BASE_RELATIVE=y
 | |
| +# CONFIG_KALLSYMS_UNCOMPRESSED is not set
 | |
| +# CONFIG_KARMA_PARTITION is not set
 | |
| +# CONFIG_KASAN is not set
 | |
| +CONFIG_KASAN_STACK=1
 | |
| +# CONFIG_KCMP is not set
 | |
| +# CONFIG_KCOV is not set
 | |
| +# CONFIG_KERNEL_BZIP2 is not set
 | |
| +# CONFIG_KERNEL_CAT is not set
 | |
| +# CONFIG_KERNEL_GZIP is not set
 | |
| +# CONFIG_KERNEL_LZ4 is not set
 | |
| +# CONFIG_KERNEL_LZMA is not set
 | |
| +# CONFIG_KERNEL_LZO is not set
 | |
| +CONFIG_KERNEL_MODE_NEON=y
 | |
| +CONFIG_KERNEL_XZ=y
 | |
| +# CONFIG_KERNEL_ZSTD is not set
 | |
| +CONFIG_KERNFS=y
 | |
| +# CONFIG_KEXEC is not set
 | |
| +# CONFIG_KEXEC_FILE is not set
 | |
| +# CONFIG_KEYBOARD_ADC is not set
 | |
| +# CONFIG_KEYBOARD_ADP5588 is not set
 | |
| +# CONFIG_KEYBOARD_ADP5589 is not set
 | |
| +# CONFIG_KEYBOARD_APPLESPI is not set
 | |
| +# CONFIG_KEYBOARD_ATKBD is not set
 | |
| +# CONFIG_KEYBOARD_BCM is not set
 | |
| +# CONFIG_KEYBOARD_CAP11XX is not set
 | |
| +# CONFIG_KEYBOARD_DLINK_DIR685 is not set
 | |
| +# CONFIG_KEYBOARD_GPIO is not set
 | |
| +# CONFIG_KEYBOARD_GPIO_POLLED is not set
 | |
| +# CONFIG_KEYBOARD_LKKBD is not set
 | |
| +# CONFIG_KEYBOARD_LM8323 is not set
 | |
| +# CONFIG_KEYBOARD_LM8333 is not set
 | |
| +# CONFIG_KEYBOARD_MATRIX is not set
 | |
| +# CONFIG_KEYBOARD_MAX7359 is not set
 | |
| +# CONFIG_KEYBOARD_MCS is not set
 | |
| +# CONFIG_KEYBOARD_MPR121 is not set
 | |
| +# CONFIG_KEYBOARD_NEWTON is not set
 | |
| +# CONFIG_KEYBOARD_OMAP4 is not set
 | |
| +# CONFIG_KEYBOARD_OPENCORES is not set
 | |
| +# CONFIG_KEYBOARD_PXA27x is not set
 | |
| +# CONFIG_KEYBOARD_QT1050 is not set
 | |
| +# CONFIG_KEYBOARD_QT1070 is not set
 | |
| +# CONFIG_KEYBOARD_QT2160 is not set
 | |
| +# CONFIG_KEYBOARD_SAMSUNG is not set
 | |
| +# CONFIG_KEYBOARD_SH_KEYSC is not set
 | |
| +# CONFIG_KEYBOARD_SNVS_PWRKEY is not set
 | |
| +# CONFIG_KEYBOARD_STMPE is not set
 | |
| +# CONFIG_KEYBOARD_STOWAWAY is not set
 | |
| +# CONFIG_KEYBOARD_SUNKBD is not set
 | |
| +# CONFIG_KEYBOARD_TCA6416 is not set
 | |
| +# CONFIG_KEYBOARD_TCA8418 is not set
 | |
| +# CONFIG_KEYBOARD_TEGRA is not set
 | |
| +# CONFIG_KEYBOARD_TM2_TOUCHKEY is not set
 | |
| +# CONFIG_KEYBOARD_TWL4030 is not set
 | |
| +# CONFIG_KEYBOARD_XTKBD is not set
 | |
| +# CONFIG_KEYS is not set
 | |
| +# CONFIG_KEYS_REQUEST_CACHE is not set
 | |
| +# CONFIG_KEY_DH_OPERATIONS is not set
 | |
| +# CONFIG_KGDB is not set
 | |
| +# CONFIG_KMEMCHECK is not set
 | |
| +# CONFIG_KMX61 is not set
 | |
| +# CONFIG_KPROBES is not set
 | |
| +# CONFIG_KPROBES_SANITY_TEST is not set
 | |
| +# CONFIG_KPROBE_EVENTS_ON_NOTRACE is not set
 | |
| +# CONFIG_KPROBE_EVENT_GEN_TEST is not set
 | |
| +# CONFIG_KS7010 is not set
 | |
| +# CONFIG_KS8842 is not set
 | |
| +# CONFIG_KS8851 is not set
 | |
| +# CONFIG_KS8851_MLL is not set
 | |
| +# CONFIG_KSM is not set
 | |
| +# CONFIG_KSZ884X_PCI is not set
 | |
| +# CONFIG_KUNIT is not set
 | |
| +CONFIG_KUSER_HELPERS=y
 | |
| +# CONFIG_KVM_AMD is not set
 | |
| +# CONFIG_KVM_AMD_SEV is not set
 | |
| +# CONFIG_KVM_GUEST is not set
 | |
| +# CONFIG_KVM_INTEL is not set
 | |
| +# CONFIG_KVM_WERROR is not set
 | |
| +# CONFIG_KXCJK1013 is not set
 | |
| +# CONFIG_KXSD9 is not set
 | |
| +# CONFIG_L2TP is not set
 | |
| +# CONFIG_L2TP_ETH is not set
 | |
| +# CONFIG_L2TP_IP is not set
 | |
| +# CONFIG_L2TP_V3 is not set
 | |
| +# CONFIG_LAN743X is not set
 | |
| +# CONFIG_LANMEDIA is not set
 | |
| +# CONFIG_LANTIQ is not set
 | |
| +# CONFIG_LAPB is not set
 | |
| +# CONFIG_LASAT is not set
 | |
| +# CONFIG_LATENCYTOP is not set
 | |
| +# CONFIG_LATTICE_ECP3_CONFIG is not set
 | |
| +CONFIG_LBDAF=y
 | |
| +# CONFIG_LCD_AMS369FG06 is not set
 | |
| +# CONFIG_LCD_CLASS_DEVICE is not set
 | |
| +# CONFIG_LCD_HX8357 is not set
 | |
| +# CONFIG_LCD_ILI922X is not set
 | |
| +# CONFIG_LCD_ILI9320 is not set
 | |
| +# CONFIG_LCD_L4F00242T03 is not set
 | |
| +# CONFIG_LCD_LD9040 is not set
 | |
| +# CONFIG_LCD_LMS283GF05 is not set
 | |
| +# CONFIG_LCD_LMS501KF03 is not set
 | |
| +# CONFIG_LCD_LTV350QV is not set
 | |
| +# CONFIG_LCD_OTM3225A is not set
 | |
| +# CONFIG_LCD_S6E63M0 is not set
 | |
| +# CONFIG_LCD_TDO24M is not set
 | |
| +# CONFIG_LCD_VGG2432A4 is not set
 | |
| +CONFIG_LDISC_AUTOLOAD=y
 | |
| +# CONFIG_LDM_PARTITION is not set
 | |
| +CONFIG_LD_DEAD_CODE_DATA_ELIMINATION=y
 | |
| +# CONFIG_LEDS_AN30259A is not set
 | |
| +# CONFIG_LEDS_APU is not set
 | |
| +# CONFIG_LEDS_AW2013 is not set
 | |
| +# CONFIG_LEDS_BCM6328 is not set
 | |
| +# CONFIG_LEDS_BCM6358 is not set
 | |
| +# CONFIG_LEDS_BD2802 is not set
 | |
| +# CONFIG_LEDS_BLINKM is not set
 | |
| +CONFIG_LEDS_BRIGHTNESS_HW_CHANGED=y
 | |
| +CONFIG_LEDS_CLASS=y
 | |
| +# CONFIG_LEDS_CLASS_FLASH is not set
 | |
| +CONFIG_LEDS_CLASS_MULTICOLOR=y
 | |
| +# CONFIG_LEDS_CR0014114 is not set
 | |
| +# CONFIG_LEDS_DAC124S085 is not set
 | |
| +# CONFIG_LEDS_EL15203000 is not set
 | |
| +# CONFIG_LEDS_GPIO is not set
 | |
| +# CONFIG_LEDS_INTEL_SS4200 is not set
 | |
| +# CONFIG_LEDS_IS31FL319X is not set
 | |
| +# CONFIG_LEDS_IS31FL32XX is not set
 | |
| +# CONFIG_LEDS_LM3530 is not set
 | |
| +# CONFIG_LEDS_LM3532 is not set
 | |
| +# CONFIG_LEDS_LM355x is not set
 | |
| +# CONFIG_LEDS_LM3642 is not set
 | |
| +# CONFIG_LEDS_LM3692X is not set
 | |
| +# CONFIG_LEDS_LP3944 is not set
 | |
| +# CONFIG_LEDS_LP3952 is not set
 | |
| +# CONFIG_LEDS_LP50XX is not set
 | |
| +# CONFIG_LEDS_LP5521 is not set
 | |
| +# CONFIG_LEDS_LP5523 is not set
 | |
| +# CONFIG_LEDS_LP5562 is not set
 | |
| +# CONFIG_LEDS_LP55XX_COMMON is not set
 | |
| +# CONFIG_LEDS_LP8501 is not set
 | |
| +# CONFIG_LEDS_LP8860 is not set
 | |
| +# CONFIG_LEDS_LT3593 is not set
 | |
| +# CONFIG_LEDS_MLXCPLD is not set
 | |
| +# CONFIG_LEDS_MLXREG is not set
 | |
| +# CONFIG_LEDS_NIC78BX is not set
 | |
| +# CONFIG_LEDS_NS2 is not set
 | |
| +# CONFIG_LEDS_OT200 is not set
 | |
| +# CONFIG_LEDS_PCA9532 is not set
 | |
| +# CONFIG_LEDS_PCA955X is not set
 | |
| +# CONFIG_LEDS_PCA963X is not set
 | |
| +# CONFIG_LEDS_PWM is not set
 | |
| +# CONFIG_LEDS_REGULATOR is not set
 | |
| +# CONFIG_LEDS_SPI_BYTE is not set
 | |
| +# CONFIG_LEDS_SYSCON is not set
 | |
| +# CONFIG_LEDS_TCA6507 is not set
 | |
| +# CONFIG_LEDS_TI_LMU_COMMON is not set
 | |
| +# CONFIG_LEDS_TLC591XX is not set
 | |
| +CONFIG_LEDS_TRIGGERS=y
 | |
| +# CONFIG_LEDS_TRIGGER_ACTIVITY is not set
 | |
| +# CONFIG_LEDS_TRIGGER_AUDIO is not set
 | |
| +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
 | |
| +# CONFIG_LEDS_TRIGGER_CAMERA is not set
 | |
| +# CONFIG_LEDS_TRIGGER_CPU is not set
 | |
| +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 | |
| +# CONFIG_LEDS_TRIGGER_DISK is not set
 | |
| +# CONFIG_LEDS_TRIGGER_GPIO is not set
 | |
| +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 | |
| +# CONFIG_LEDS_TRIGGER_MTD is not set
 | |
| +CONFIG_LEDS_TRIGGER_NETDEV=y
 | |
| +# CONFIG_LEDS_TRIGGER_ONESHOT is not set
 | |
| +# CONFIG_LEDS_TRIGGER_PANIC is not set
 | |
| +# CONFIG_LEDS_TRIGGER_PATTERN is not set
 | |
| +CONFIG_LEDS_TRIGGER_TIMER=y
 | |
| +# CONFIG_LEDS_TRIGGER_TRANSIENT is not set
 | |
| +# CONFIG_LEDS_TURRIS_OMNIA is not set
 | |
| +# CONFIG_LEDS_USER is not set
 | |
| +# CONFIG_LED_TRIGGER_PHY is not set
 | |
| +# CONFIG_LEGACY_PTYS is not set
 | |
| +# CONFIG_LGUEST is not set
 | |
| +# CONFIG_LIB80211 is not set
 | |
| +# CONFIG_LIB80211_CRYPT_CCMP is not set
 | |
| +# CONFIG_LIB80211_CRYPT_TKIP is not set
 | |
| +# CONFIG_LIB80211_CRYPT_WEP is not set
 | |
| +# CONFIG_LIB80211_DEBUG is not set
 | |
| +# CONFIG_LIBCRC32C is not set
 | |
| +# CONFIG_LIBERTAS is not set
 | |
| +# CONFIG_LIBERTAS_THINFIRM is not set
 | |
| +# CONFIG_LIBERTAS_USB is not set
 | |
| +# CONFIG_LIBFC is not set
 | |
| +# CONFIG_LIBFCOE is not set
 | |
| +# CONFIG_LIBIPW_DEBUG is not set
 | |
| +# CONFIG_LIBNVDIMM is not set
 | |
| +# CONFIG_LIDAR_LITE_V2 is not set
 | |
| +CONFIG_LINEAR_RANGES=y
 | |
| +# CONFIG_LIQUIDIO is not set
 | |
| +# CONFIG_LIQUIDIO_VF is not set
 | |
| +# CONFIG_LIS3L02DQ is not set
 | |
| +# CONFIG_LKDTM is not set
 | |
| +CONFIG_LLC=y
 | |
| +# CONFIG_LLC2 is not set
 | |
| +# CONFIG_LMP91000 is not set
 | |
| +# CONFIG_LNET is not set
 | |
| +CONFIG_LOCALVERSION=""
 | |
| +# CONFIG_LOCALVERSION_AUTO is not set
 | |
| +# CONFIG_LOCKD is not set
 | |
| +CONFIG_LOCKDEP_SUPPORT=y
 | |
| +CONFIG_LOCKD_V4=y
 | |
| +# CONFIG_LOCKUP_DETECTOR is not set
 | |
| +# CONFIG_LOCK_EVENT_COUNTS is not set
 | |
| +# CONFIG_LOCK_STAT is not set
 | |
| +# CONFIG_LOCK_TORTURE_TEST is not set
 | |
| +# CONFIG_LOGFS is not set
 | |
| +# CONFIG_LOGIG940_FF is not set
 | |
| +# CONFIG_LOGIRUMBLEPAD2_FF is not set
 | |
| +# CONFIG_LOGITECH_FF is not set
 | |
| +# CONFIG_LOGIWHEELS_FF is not set
 | |
| +# CONFIG_LOGO is not set
 | |
| +CONFIG_LOG_BUF_SHIFT=17
 | |
| +CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
 | |
| +# CONFIG_LOONGSON_MC146818 is not set
 | |
| +# CONFIG_LPC_ICH is not set
 | |
| +# CONFIG_LPC_SCH is not set
 | |
| +# CONFIG_LP_CONSOLE is not set
 | |
| +# CONFIG_LSI_ET1011C_PHY is not set
 | |
| +CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity"
 | |
| +CONFIG_LSM_MMAP_MIN_ADDR=65536
 | |
| +# CONFIG_LTC1660 is not set
 | |
| +# CONFIG_LTC2471 is not set
 | |
| +# CONFIG_LTC2485 is not set
 | |
| +# CONFIG_LTC2496 is not set
 | |
| +# CONFIG_LTC2497 is not set
 | |
| +# CONFIG_LTC2632 is not set
 | |
| +# CONFIG_LTC2983 is not set
 | |
| +# CONFIG_LTE_GDM724X is not set
 | |
| +# CONFIG_LTPC is not set
 | |
| +# CONFIG_LTR501 is not set
 | |
| +# CONFIG_LUSTRE_FS is not set
 | |
| +# CONFIG_LV0104CS is not set
 | |
| +# CONFIG_LWTUNNEL is not set
 | |
| +# CONFIG_LXT_PHY is not set
 | |
| +# CONFIG_LZ4HC_COMPRESS is not set
 | |
| +# CONFIG_LZ4_COMPRESS is not set
 | |
| +# CONFIG_LZ4_DECOMPRESS is not set
 | |
| +CONFIG_LZMA_COMPRESS=y
 | |
| +CONFIG_LZMA_DECOMPRESS=y
 | |
| +# CONFIG_LZO_COMPRESS is not set
 | |
| +# CONFIG_LZO_DECOMPRESS is not set
 | |
| +# CONFIG_M62332 is not set
 | |
| +# CONFIG_MAC80211 is not set
 | |
| +# CONFIG_MAC80211_MESSAGE_TRACING is not set
 | |
| +CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
 | |
| +# CONFIG_MACB is not set
 | |
| +# CONFIG_MACH_ASM9260 is not set
 | |
| +# CONFIG_MACH_DECSTATION is not set
 | |
| +# CONFIG_MACH_INGENIC is not set
 | |
| +# CONFIG_MACH_INGENIC_SOC is not set
 | |
| +# CONFIG_MACH_JAZZ is not set
 | |
| +# CONFIG_MACH_JZ4740 is not set
 | |
| +# CONFIG_MACH_LOONGSON2EF is not set
 | |
| +# CONFIG_MACH_LOONGSON32 is not set
 | |
| +# CONFIG_MACH_LOONGSON64 is not set
 | |
| +# CONFIG_MACH_PIC32 is not set
 | |
| +# CONFIG_MACH_PISTACHIO is not set
 | |
| +# CONFIG_MACH_TX39XX is not set
 | |
| +# CONFIG_MACH_TX49XX is not set
 | |
| +# CONFIG_MACH_VR41XX is not set
 | |
| +# CONFIG_MACH_XILFPGA is not set
 | |
| +# CONFIG_MACINTOSH_DRIVERS is not set
 | |
| +# CONFIG_MACSEC is not set
 | |
| +# CONFIG_MACVLAN is not set
 | |
| +# CONFIG_MACVTAP is not set
 | |
| +# CONFIG_MAC_EMUMOUSEBTN is not set
 | |
| +# CONFIG_MAC_PARTITION is not set
 | |
| +# CONFIG_MAG3110 is not set
 | |
| +# CONFIG_MAGIC_SYSRQ is not set
 | |
| +CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x1
 | |
| +# CONFIG_MAGIC_SYSRQ_SERIAL is not set
 | |
| +CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE=""
 | |
| +# CONFIG_MAILBOX is not set
 | |
| +# CONFIG_MANAGER_SBS is not set
 | |
| +# CONFIG_MANDATORY_FILE_LOCKING is not set
 | |
| +# CONFIG_MANGLE_BOOTARGS is not set
 | |
| +# CONFIG_MARVELL_10G_PHY is not set
 | |
| +# CONFIG_MARVELL_PHY is not set
 | |
| +# CONFIG_MAX1027 is not set
 | |
| +# CONFIG_MAX11100 is not set
 | |
| +# CONFIG_MAX1118 is not set
 | |
| +# CONFIG_MAX1241 is not set
 | |
| +# CONFIG_MAX1363 is not set
 | |
| +# CONFIG_MAX30100 is not set
 | |
| +# CONFIG_MAX30102 is not set
 | |
| +# CONFIG_MAX31856 is not set
 | |
| +# CONFIG_MAX44000 is not set
 | |
| +# CONFIG_MAX44009 is not set
 | |
| +# CONFIG_MAX517 is not set
 | |
| +# CONFIG_MAX5432 is not set
 | |
| +# CONFIG_MAX5481 is not set
 | |
| +# CONFIG_MAX5487 is not set
 | |
| +# CONFIG_MAX5821 is not set
 | |
| +# CONFIG_MAX63XX_WATCHDOG is not set
 | |
| +# CONFIG_MAX9611 is not set
 | |
| +# CONFIG_MAXIM_THERMOCOUPLE is not set
 | |
| +CONFIG_MAY_USE_DEVLINK=y
 | |
| +# CONFIG_MB1232 is not set
 | |
| +# CONFIG_MC3230 is not set
 | |
| +# CONFIG_MCB is not set
 | |
| +# CONFIG_MCP320X is not set
 | |
| +# CONFIG_MCP3422 is not set
 | |
| +# CONFIG_MCP3911 is not set
 | |
| +# CONFIG_MCP4018 is not set
 | |
| +# CONFIG_MCP41010 is not set
 | |
| +# CONFIG_MCP4131 is not set
 | |
| +# CONFIG_MCP4531 is not set
 | |
| +# CONFIG_MCP4725 is not set
 | |
| +# CONFIG_MCP4922 is not set
 | |
| +# CONFIG_MCPM is not set
 | |
| +# CONFIG_MD is not set
 | |
| +# CONFIG_MDIO_BCM_UNIMAC is not set
 | |
| +# CONFIG_MDIO_BITBANG is not set
 | |
| +# CONFIG_MDIO_BUS_MUX_GPIO is not set
 | |
| +# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
 | |
| +# CONFIG_MDIO_BUS_MUX_MULTIPLEXER is not set
 | |
| +# CONFIG_MDIO_DEVICE is not set
 | |
| +# CONFIG_MDIO_DEVRES is not set
 | |
| +# CONFIG_MDIO_HISI_FEMAC is not set
 | |
| +# CONFIG_MDIO_IPQ4019 is not set
 | |
| +# CONFIG_MDIO_IPQ8064 is not set
 | |
| +# CONFIG_MDIO_MSCC_MIIM is not set
 | |
| +# CONFIG_MDIO_MVUSB is not set
 | |
| +# CONFIG_MDIO_OCTEON is not set
 | |
| +# CONFIG_MDIO_THUNDER is not set
 | |
| +# CONFIG_MDIO_XPCS is not set
 | |
| +# CONFIG_MD_FAULTY is not set
 | |
| +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_ATTACH is not set
 | |
| +# CONFIG_MEDIA_CAMERA_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_CEC_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_CONTROLLER is not set
 | |
| +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_PCI_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_PLATFORM_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_RADIO_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_RC_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_SDR_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
 | |
| +# CONFIG_MEDIA_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_SUPPORT_FILTER is not set
 | |
| +# CONFIG_MEDIA_TEST_SUPPORT is not set
 | |
| +# CONFIG_MEDIA_TUNER_E4000 is not set
 | |
| +# CONFIG_MEDIA_TUNER_FC0011 is not set
 | |
| +# CONFIG_MEDIA_TUNER_FC0012 is not set
 | |
| +# CONFIG_MEDIA_TUNER_FC0013 is not set
 | |
| +# CONFIG_MEDIA_TUNER_FC2580 is not set
 | |
| +# CONFIG_MEDIA_TUNER_IT913X is not set
 | |
| +# CONFIG_MEDIA_TUNER_M88RS6000T is not set
 | |
| +# CONFIG_MEDIA_TUNER_MAX2165 is not set
 | |
| +# CONFIG_MEDIA_TUNER_MC44S803 is not set
 | |
| +# CONFIG_MEDIA_TUNER_MSI001 is not set
 | |
| +# CONFIG_MEDIA_TUNER_MT2060 is not set
 | |
| +# CONFIG_MEDIA_TUNER_MT2063 is not set
 | |
| +# CONFIG_MEDIA_TUNER_MT20XX is not set
 | |
| +# CONFIG_MEDIA_TUNER_MT2131 is not set
 | |
| +# CONFIG_MEDIA_TUNER_MT2266 is not set
 | |
| +# CONFIG_MEDIA_TUNER_MXL301RF is not set
 | |
| +# CONFIG_MEDIA_TUNER_MXL5005S is not set
 | |
| +# CONFIG_MEDIA_TUNER_MXL5007T is not set
 | |
| +# CONFIG_MEDIA_TUNER_QM1D1B0004 is not set
 | |
| +# CONFIG_MEDIA_TUNER_QM1D1C0042 is not set
 | |
| +# CONFIG_MEDIA_TUNER_QT1010 is not set
 | |
| +# CONFIG_MEDIA_TUNER_R820T is not set
 | |
| +# CONFIG_MEDIA_TUNER_SI2157 is not set
 | |
| +# CONFIG_MEDIA_TUNER_SIMPLE is not set
 | |
| +# CONFIG_MEDIA_TUNER_TDA18212 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TDA18218 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TDA18250 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TDA18271 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TDA827X is not set
 | |
| +# CONFIG_MEDIA_TUNER_TDA8290 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TDA9887 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TEA5761 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TEA5767 is not set
 | |
| +# CONFIG_MEDIA_TUNER_TUA9001 is not set
 | |
| +# CONFIG_MEDIA_TUNER_XC2028 is not set
 | |
| +# CONFIG_MEDIA_TUNER_XC4000 is not set
 | |
| +# CONFIG_MEDIA_TUNER_XC5000 is not set
 | |
| +# CONFIG_MEDIA_USB_SUPPORT is not set
 | |
| +# CONFIG_MEGARAID_LEGACY is not set
 | |
| +# CONFIG_MEGARAID_NEWGEN is not set
 | |
| +# CONFIG_MEGARAID_SAS is not set
 | |
| +# CONFIG_MELLANOX_PLATFORM is not set
 | |
| +CONFIG_MEMBARRIER=y
 | |
| +# CONFIG_MEMORY is not set
 | |
| +# CONFIG_MEMORY_FAILURE is not set
 | |
| +# CONFIG_MEMORY_HOTPLUG is not set
 | |
| +# CONFIG_MEMSTICK is not set
 | |
| +# CONFIG_MEMTEST is not set
 | |
| +# CONFIG_MEN_A21_WDT is not set
 | |
| +# CONFIG_MESON_SM is not set
 | |
| +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
 | |
| +# CONFIG_MFD_88PM800 is not set
 | |
| +# CONFIG_MFD_88PM805 is not set
 | |
| +# CONFIG_MFD_88PM860X is not set
 | |
| +# CONFIG_MFD_AAT2870_CORE is not set
 | |
| +# CONFIG_MFD_AC100 is not set
 | |
| +# CONFIG_MFD_ACT8945A is not set
 | |
| +# CONFIG_MFD_ARIZONA_I2C is not set
 | |
| +# CONFIG_MFD_ARIZONA_SPI is not set
 | |
| +# CONFIG_MFD_AS3711 is not set
 | |
| +# CONFIG_MFD_AS3722 is not set
 | |
| +# CONFIG_MFD_ASIC3 is not set
 | |
| +# CONFIG_MFD_ATMEL_FLEXCOM is not set
 | |
| +# CONFIG_MFD_ATMEL_HLCDC is not set
 | |
| +# CONFIG_MFD_AXP20X is not set
 | |
| +# CONFIG_MFD_AXP20X_I2C is not set
 | |
| +# CONFIG_MFD_BCM590XX is not set
 | |
| +# CONFIG_MFD_BD9571MWV is not set
 | |
| +# CONFIG_MFD_CORE is not set
 | |
| +# CONFIG_MFD_CPCAP is not set
 | |
| +# CONFIG_MFD_CROS_EC is not set
 | |
| +# CONFIG_MFD_CS5535 is not set
 | |
| +# CONFIG_MFD_DA9052_I2C is not set
 | |
| +# CONFIG_MFD_DA9052_SPI is not set
 | |
| +# CONFIG_MFD_DA9055 is not set
 | |
| +# CONFIG_MFD_DA9062 is not set
 | |
| +# CONFIG_MFD_DA9063 is not set
 | |
| +# CONFIG_MFD_DA9150 is not set
 | |
| +# CONFIG_MFD_DLN2 is not set
 | |
| +# CONFIG_MFD_EXYNOS_LPASS is not set
 | |
| +# CONFIG_MFD_GATEWORKS_GSC is not set
 | |
| +# CONFIG_MFD_HI6421_PMIC is not set
 | |
| +# CONFIG_MFD_INTEL_M10_BMC is not set
 | |
| +# CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set
 | |
| +# CONFIG_MFD_IQS62X is not set
 | |
| +# CONFIG_MFD_JANZ_CMODIO is not set
 | |
| +# CONFIG_MFD_KEMPLD is not set
 | |
| +# CONFIG_MFD_LM3533 is not set
 | |
| +# CONFIG_MFD_LOCHNAGAR is not set
 | |
| +# CONFIG_MFD_LP3943 is not set
 | |
| +# CONFIG_MFD_LP8788 is not set
 | |
| +# CONFIG_MFD_MADERA is not set
 | |
| +# CONFIG_MFD_MAX14577 is not set
 | |
| +# CONFIG_MFD_MAX77620 is not set
 | |
| +# CONFIG_MFD_MAX77650 is not set
 | |
| +# CONFIG_MFD_MAX77686 is not set
 | |
| +# CONFIG_MFD_MAX77693 is not set
 | |
| +# CONFIG_MFD_MAX77843 is not set
 | |
| +# CONFIG_MFD_MAX8907 is not set
 | |
| +# CONFIG_MFD_MAX8925 is not set
 | |
| +# CONFIG_MFD_MAX8997 is not set
 | |
| +# CONFIG_MFD_MAX8998 is not set
 | |
| +# CONFIG_MFD_MC13XXX is not set
 | |
| +# CONFIG_MFD_MC13XXX_I2C is not set
 | |
| +# CONFIG_MFD_MC13XXX_SPI is not set
 | |
| +# CONFIG_MFD_MENF21BMC is not set
 | |
| +# CONFIG_MFD_MP2629 is not set
 | |
| +# CONFIG_MFD_MT6360 is not set
 | |
| +# CONFIG_MFD_MT6397 is not set
 | |
| +# CONFIG_MFD_OMAP_USB_HOST is not set
 | |
| +# CONFIG_MFD_PALMAS is not set
 | |
| +# CONFIG_MFD_PCF50633 is not set
 | |
| +# CONFIG_MFD_PM8921_CORE is not set
 | |
| +# CONFIG_MFD_PM8XXX is not set
 | |
| +# CONFIG_MFD_RC5T583 is not set
 | |
| +# CONFIG_MFD_RDC321X is not set
 | |
| +# CONFIG_MFD_RETU is not set
 | |
| +# CONFIG_MFD_RK808 is not set
 | |
| +# CONFIG_MFD_RN5T618 is not set
 | |
| +# CONFIG_MFD_ROHM_BD70528 is not set
 | |
| +# CONFIG_MFD_ROHM_BD71828 is not set
 | |
| +# CONFIG_MFD_ROHM_BD718XX is not set
 | |
| +# CONFIG_MFD_RT5033 is not set
 | |
| +# CONFIG_MFD_RTSX_PCI is not set
 | |
| +# CONFIG_MFD_RTSX_USB is not set
 | |
| +# CONFIG_MFD_SEC_CORE is not set
 | |
| +# CONFIG_MFD_SI476X_CORE is not set
 | |
| +# CONFIG_MFD_SKY81452 is not set
 | |
| +# CONFIG_MFD_SM501 is not set
 | |
| +# CONFIG_MFD_SMSC is not set
 | |
| +# CONFIG_MFD_STMFX is not set
 | |
| +# CONFIG_MFD_STMPE is not set
 | |
| +# CONFIG_MFD_STPMIC1 is not set
 | |
| +# CONFIG_MFD_SYSCON is not set
 | |
| +# CONFIG_MFD_T7L66XB is not set
 | |
| +# CONFIG_MFD_TC3589X is not set
 | |
| +# CONFIG_MFD_TC6387XB is not set
 | |
| +# CONFIG_MFD_TC6393XB is not set
 | |
| +# CONFIG_MFD_TIMBERDALE is not set
 | |
| +# CONFIG_MFD_TI_AM335X_TSCADC is not set
 | |
| +# CONFIG_MFD_TI_LMU is not set
 | |
| +# CONFIG_MFD_TI_LP873X is not set
 | |
| +# CONFIG_MFD_TI_LP87565 is not set
 | |
| +# CONFIG_MFD_TMIO is not set
 | |
| +# CONFIG_MFD_TPS65086 is not set
 | |
| +# CONFIG_MFD_TPS65090 is not set
 | |
| +# CONFIG_MFD_TPS65217 is not set
 | |
| +# CONFIG_MFD_TPS65218 is not set
 | |
| +# CONFIG_MFD_TPS6586X is not set
 | |
| +# CONFIG_MFD_TPS65910 is not set
 | |
| +# CONFIG_MFD_TPS65912 is not set
 | |
| +# CONFIG_MFD_TPS65912_I2C is not set
 | |
| +# CONFIG_MFD_TPS65912_SPI is not set
 | |
| +# CONFIG_MFD_TPS68470 is not set
 | |
| +# CONFIG_MFD_TPS80031 is not set
 | |
| +# CONFIG_MFD_TQMX86 is not set
 | |
| +# CONFIG_MFD_VIPERBOARD is not set
 | |
| +# CONFIG_MFD_VX855 is not set
 | |
| +# CONFIG_MFD_WL1273_CORE is not set
 | |
| +# CONFIG_MFD_WM831X is not set
 | |
| +# CONFIG_MFD_WM831X_I2C is not set
 | |
| +# CONFIG_MFD_WM831X_SPI is not set
 | |
| +# CONFIG_MFD_WM8350_I2C is not set
 | |
| +# CONFIG_MFD_WM8400 is not set
 | |
| +# CONFIG_MFD_WM8994 is not set
 | |
| +# CONFIG_MG_DISK is not set
 | |
| +# CONFIG_MHI_BUS is not set
 | |
| +# CONFIG_MICREL_KS8995MA is not set
 | |
| +# CONFIG_MICREL_PHY is not set
 | |
| +# CONFIG_MICROCHIP_KSZ is not set
 | |
| +# CONFIG_MICROCHIP_PHY is not set
 | |
| +# CONFIG_MICROCHIP_PIT64B is not set
 | |
| +# CONFIG_MICROCHIP_T1_PHY is not set
 | |
| +# CONFIG_MICROSEMI_PHY is not set
 | |
| +# CONFIG_MIGRATION is not set
 | |
| +CONFIG_MII=y
 | |
| +# CONFIG_MIKROTIK is not set
 | |
| +# CONFIG_MIKROTIK_RB532 is not set
 | |
| +# CONFIG_MINIX_FS is not set
 | |
| +# CONFIG_MINIX_FS_NATIVE_ENDIAN is not set
 | |
| +# CONFIG_MINIX_SUBPARTITION is not set
 | |
| +# CONFIG_MIPS_ALCHEMY is not set
 | |
| +# CONFIG_MIPS_CDMM is not set
 | |
| +# CONFIG_MIPS_COBALT is not set
 | |
| +# CONFIG_MIPS_FPU_EMULATOR is not set
 | |
| +# CONFIG_MIPS_FP_SUPPORT is not set
 | |
| +# CONFIG_MIPS_GENERIC is not set
 | |
| +# CONFIG_MIPS_GENERIC_KERNEL is not set
 | |
| +# CONFIG_MIPS_MALTA is not set
 | |
| +# CONFIG_MIPS_O32_FP64_SUPPORT is not set
 | |
| +# CONFIG_MIPS_PARAVIRT is not set
 | |
| +# CONFIG_MIPS_PLATFORM_DEVICES is not set
 | |
| +# CONFIG_MIPS_SEAD3 is not set
 | |
| +# CONFIG_MISC_ALCOR_PCI is not set
 | |
| +CONFIG_MISC_FILESYSTEMS=y
 | |
| +# CONFIG_MISC_RTSX_PCI is not set
 | |
| +# CONFIG_MISC_RTSX_USB is not set
 | |
| +# CONFIG_MISDN is not set
 | |
| +# CONFIG_MISDN_AVMFRITZ is not set
 | |
| +# CONFIG_MISDN_HFCPCI is not set
 | |
| +# CONFIG_MISDN_HFCUSB is not set
 | |
| +# CONFIG_MISDN_INFINEON is not set
 | |
| +# CONFIG_MISDN_NETJET is not set
 | |
| +# CONFIG_MISDN_SPEEDFAX is not set
 | |
| +# CONFIG_MISDN_W6692 is not set
 | |
| +# CONFIG_MKISS is not set
 | |
| +# CONFIG_MLX4_CORE is not set
 | |
| +# CONFIG_MLX4_EN is not set
 | |
| +# CONFIG_MLX5_CORE is not set
 | |
| +# CONFIG_MLX90614 is not set
 | |
| +# CONFIG_MLX90632 is not set
 | |
| +# CONFIG_MLXFW is not set
 | |
| +# CONFIG_MLXSW_CORE is not set
 | |
| +# CONFIG_MLX_CPLD_PLATFORM is not set
 | |
| +# CONFIG_MLX_PLATFORM is not set
 | |
| +# CONFIG_MMA7455_I2C is not set
 | |
| +# CONFIG_MMA7455_SPI is not set
 | |
| +# CONFIG_MMA7660 is not set
 | |
| +# CONFIG_MMA8452 is not set
 | |
| +# CONFIG_MMA9551 is not set
 | |
| +# CONFIG_MMA9553 is not set
 | |
| +# CONFIG_MMC is not set
 | |
| +# CONFIG_MMC35240 is not set
 | |
| +# CONFIG_MMC_ARMMMCI is not set
 | |
| +# CONFIG_MMC_AU1X is not set
 | |
| +# CONFIG_MMC_BLOCK is not set
 | |
| +CONFIG_MMC_BLOCK_BOUNCE=y
 | |
| +CONFIG_MMC_BLOCK_MINORS=8
 | |
| +# CONFIG_MMC_CAVIUM_THUNDERX is not set
 | |
| +# CONFIG_MMC_CB710 is not set
 | |
| +# CONFIG_MMC_CQHCI is not set
 | |
| +# CONFIG_MMC_DEBUG is not set
 | |
| +# CONFIG_MMC_DW is not set
 | |
| +# CONFIG_MMC_HSQ is not set
 | |
| +# CONFIG_MMC_JZ4740 is not set
 | |
| +# CONFIG_MMC_MTK is not set
 | |
| +# CONFIG_MMC_MVSDIO is not set
 | |
| +# CONFIG_MMC_S3C is not set
 | |
| +# CONFIG_MMC_SDHCI is not set
 | |
| +# CONFIG_MMC_SDHCI_ACPI is not set
 | |
| +# CONFIG_MMC_SDHCI_AM654 is not set
 | |
| +# CONFIG_MMC_SDHCI_BCM_KONA is not set
 | |
| +# CONFIG_MMC_SDHCI_CADENCE is not set
 | |
| +# CONFIG_MMC_SDHCI_F_SDH30 is not set
 | |
| +# CONFIG_MMC_SDHCI_IPROC is not set
 | |
| +# CONFIG_MMC_SDHCI_MILBEAUT is not set
 | |
| +# CONFIG_MMC_SDHCI_MSM is not set
 | |
| +# CONFIG_MMC_SDHCI_OF_ARASAN is not set
 | |
| +# CONFIG_MMC_SDHCI_OF_ASPEED is not set
 | |
| +# CONFIG_MMC_SDHCI_OF_AT91 is not set
 | |
| +# CONFIG_MMC_SDHCI_OF_DWCMSHC is not set
 | |
| +# CONFIG_MMC_SDHCI_OF_ESDHC is not set
 | |
| +# CONFIG_MMC_SDHCI_OF_HLWD is not set
 | |
| +# CONFIG_MMC_SDHCI_OMAP is not set
 | |
| +# CONFIG_MMC_SDHCI_PXAV2 is not set
 | |
| +# CONFIG_MMC_SDHCI_PXAV3 is not set
 | |
| +# CONFIG_MMC_SDHCI_S3C is not set
 | |
| +# CONFIG_MMC_SDHCI_XENON is not set
 | |
| +# CONFIG_MMC_SDRICOH_CS is not set
 | |
| +# CONFIG_MMC_SPI is not set
 | |
| +# CONFIG_MMC_STM32_SDMMC is not set
 | |
| +# CONFIG_MMC_TEST is not set
 | |
| +# CONFIG_MMC_TIFM_SD is not set
 | |
| +# CONFIG_MMC_TOSHIBA_PCI is not set
 | |
| +# CONFIG_MMC_USDHI6ROL0 is not set
 | |
| +# CONFIG_MMC_USHC is not set
 | |
| +# CONFIG_MMC_VIA_SDMMC is not set
 | |
| +# CONFIG_MMC_VUB300 is not set
 | |
| +# CONFIG_MMIOTRACE is not set
 | |
| +CONFIG_MMU=y
 | |
| +CONFIG_MMU_GATHER_RCU_TABLE_FREE=y
 | |
| +CONFIG_MMU_GATHER_TABLE_FREE=y
 | |
| +CONFIG_MODULES=y
 | |
| +# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
 | |
| +# CONFIG_MODULE_COMPRESS is not set
 | |
| +# CONFIG_MODULE_FORCE_LOAD is not set
 | |
| +# CONFIG_MODULE_FORCE_UNLOAD is not set
 | |
| +# CONFIG_MODULE_SIG is not set
 | |
| +# CONFIG_MODULE_SRCVERSION_ALL is not set
 | |
| +CONFIG_MODULE_STRIPPED=y
 | |
| +CONFIG_MODULE_UNLOAD=y
 | |
| +# CONFIG_MODVERSIONS is not set
 | |
| +# CONFIG_MOST is not set
 | |
| +# CONFIG_MOUSE_APPLETOUCH is not set
 | |
| +# CONFIG_MOUSE_ELAN_I2C is not set
 | |
| +# CONFIG_MOUSE_GPIO is not set
 | |
| +# CONFIG_MOUSE_INPORT is not set
 | |
| +# CONFIG_MOUSE_LOGIBM is not set
 | |
| +# CONFIG_MOUSE_PC110PAD is not set
 | |
| +# CONFIG_MOUSE_PS2_FOCALTECH is not set
 | |
| +# CONFIG_MOUSE_PS2_SENTELIC is not set
 | |
| +# CONFIG_MOUSE_SYNAPTICS_I2C is not set
 | |
| +# CONFIG_MOUSE_SYNAPTICS_USB is not set
 | |
| +# CONFIG_MOXTET is not set
 | |
| +# CONFIG_MPL115 is not set
 | |
| +# CONFIG_MPL115_I2C is not set
 | |
| +# CONFIG_MPL115_SPI is not set
 | |
| +# CONFIG_MPL3115 is not set
 | |
| +# CONFIG_MPLS is not set
 | |
| +# CONFIG_MPTCP is not set
 | |
| +# CONFIG_MPU3050_I2C is not set
 | |
| +# CONFIG_MQ_IOSCHED_DEADLINE is not set
 | |
| +# CONFIG_MQ_IOSCHED_KYBER is not set
 | |
| +# CONFIG_MS5611 is not set
 | |
| +# CONFIG_MS5637 is not set
 | |
| +# CONFIG_MSCC_OCELOT_SWITCH is not set
 | |
| +# CONFIG_MSDOS_FS is not set
 | |
| +CONFIG_MSDOS_PARTITION=y
 | |
| +# CONFIG_MSI_BITMAP_SELFTEST is not set
 | |
| +# CONFIG_MSI_LAPTOP is not set
 | |
| +# CONFIG_MST_IRQ is not set
 | |
| +CONFIG_MTD=y
 | |
| +# CONFIG_MTD_ABSENT is not set
 | |
| +# CONFIG_MTD_AFS_PARTS is not set
 | |
| +# CONFIG_MTD_AR7_PARTS is not set
 | |
| +CONFIG_MTD_BLKDEVS=y
 | |
| +CONFIG_MTD_BLOCK=y
 | |
| +# CONFIG_MTD_BLOCK2MTD is not set
 | |
| +CONFIG_MTD_CFI=y
 | |
| +# CONFIG_MTD_CFI_ADV_OPTIONS is not set
 | |
| +CONFIG_MTD_CFI_AMDSTD=y
 | |
| +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
 | |
| +CONFIG_MTD_CFI_I1=y
 | |
| +CONFIG_MTD_CFI_I2=y
 | |
| +# CONFIG_MTD_CFI_I4 is not set
 | |
| +# CONFIG_MTD_CFI_I8 is not set
 | |
| +CONFIG_MTD_CFI_INTELEXT=y
 | |
| +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
 | |
| +CONFIG_MTD_CFI_NOSWAP=y
 | |
| +# CONFIG_MTD_CFI_STAA is not set
 | |
| +CONFIG_MTD_CFI_UTIL=y
 | |
| +# CONFIG_MTD_CMDLINE_PARTS is not set
 | |
| +CONFIG_MTD_COMPLEX_MAPPINGS=y
 | |
| +# CONFIG_MTD_DATAFLASH is not set
 | |
| +# CONFIG_MTD_DOCG3 is not set
 | |
| +CONFIG_MTD_GEN_PROBE=y
 | |
| +# CONFIG_MTD_GPIO_ADDR is not set
 | |
| +# CONFIG_MTD_HYPERBUS is not set
 | |
| +# CONFIG_MTD_IMPA7 is not set
 | |
| +# CONFIG_MTD_INTEL_VR_NOR is not set
 | |
| +# CONFIG_MTD_JEDECPROBE is not set
 | |
| +# CONFIG_MTD_LATCH_ADDR is not set
 | |
| +# CONFIG_MTD_LPDDR is not set
 | |
| +# CONFIG_MTD_LPDDR2_NVM is not set
 | |
| +# CONFIG_MTD_M25P80 is not set
 | |
| +CONFIG_MTD_MAP_BANK_WIDTH_1=y
 | |
| +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
 | |
| +CONFIG_MTD_MAP_BANK_WIDTH_2=y
 | |
| +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
 | |
| +CONFIG_MTD_MAP_BANK_WIDTH_4=y
 | |
| +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
 | |
| +# CONFIG_MTD_MCHP23K256 is not set
 | |
| +# CONFIG_MTD_MT81xx_NOR is not set
 | |
| +# CONFIG_MTD_MTDRAM is not set
 | |
| +# CONFIG_MTD_MYLOADER_PARTS is not set
 | |
| +# CONFIG_MTD_NAND is not set
 | |
| +# CONFIG_MTD_NAND_AMS_DELTA is not set
 | |
| +# CONFIG_MTD_NAND_AR934X is not set
 | |
| +# CONFIG_MTD_NAND_AR934X_HW_ECC is not set
 | |
| +# CONFIG_MTD_NAND_ARASAN is not set
 | |
| +# CONFIG_MTD_NAND_ATMEL is not set
 | |
| +# CONFIG_MTD_NAND_AU1550 is not set
 | |
| +# CONFIG_MTD_NAND_BCH is not set
 | |
| +# CONFIG_MTD_NAND_BF5XX is not set
 | |
| +# CONFIG_MTD_NAND_BRCMNAND is not set
 | |
| +# CONFIG_MTD_NAND_CADENCE is not set
 | |
| +# CONFIG_MTD_NAND_CAFE is not set
 | |
| +# CONFIG_MTD_NAND_CM_X270 is not set
 | |
| +# CONFIG_MTD_NAND_CS553X is not set
 | |
| +# CONFIG_MTD_NAND_DAVINCI is not set
 | |
| +# CONFIG_MTD_NAND_DENALI is not set
 | |
| +# CONFIG_MTD_NAND_DENALI_DT is not set
 | |
| +# CONFIG_MTD_NAND_DENALI_PCI is not set
 | |
| +CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018
 | |
| +# CONFIG_MTD_NAND_DISKONCHIP is not set
 | |
| +# CONFIG_MTD_NAND_DOCG4 is not set
 | |
| +# CONFIG_MTD_NAND_ECC is not set
 | |
| +# CONFIG_MTD_NAND_ECC_BCH is not set
 | |
| +# CONFIG_MTD_NAND_ECC_SMC is not set
 | |
| +# CONFIG_MTD_NAND_ECC_SW_BCH is not set
 | |
| +# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set
 | |
| +# CONFIG_MTD_NAND_FSL_ELBC is not set
 | |
| +# CONFIG_MTD_NAND_FSL_IFC is not set
 | |
| +# CONFIG_MTD_NAND_FSL_UPM is not set
 | |
| +# CONFIG_MTD_NAND_FSMC is not set
 | |
| +# CONFIG_MTD_NAND_GPIO is not set
 | |
| +# CONFIG_MTD_NAND_GPMI_NAND is not set
 | |
| +# CONFIG_MTD_NAND_HISI504 is not set
 | |
| +CONFIG_MTD_NAND_IDS=y
 | |
| +# CONFIG_MTD_NAND_JZ4740 is not set
 | |
| +# CONFIG_MTD_NAND_MPC5121_NFC is not set
 | |
| +# CONFIG_MTD_NAND_MTK is not set
 | |
| +# CONFIG_MTD_NAND_MXC is not set
 | |
| +# CONFIG_MTD_NAND_MXIC is not set
 | |
| +# CONFIG_MTD_NAND_NANDSIM is not set
 | |
| +# CONFIG_MTD_NAND_NDFC is not set
 | |
| +# CONFIG_MTD_NAND_NUC900 is not set
 | |
| +# CONFIG_MTD_NAND_OMAP2 is not set
 | |
| +# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set
 | |
| +# CONFIG_MTD_NAND_ORION is not set
 | |
| +# CONFIG_MTD_NAND_PASEMI is not set
 | |
| +# CONFIG_MTD_NAND_PLATFORM is not set
 | |
| +# CONFIG_MTD_NAND_PXA3xx is not set
 | |
| +# CONFIG_MTD_NAND_RB4XX is not set
 | |
| +# CONFIG_MTD_NAND_RB750 is not set
 | |
| +# CONFIG_MTD_NAND_RICOH is not set
 | |
| +# CONFIG_MTD_NAND_S3C2410 is not set
 | |
| +# CONFIG_MTD_NAND_SHARPSL is not set
 | |
| +# CONFIG_MTD_NAND_SH_FLCTL is not set
 | |
| +# CONFIG_MTD_NAND_SOCRATES is not set
 | |
| +# CONFIG_MTD_NAND_TMIO is not set
 | |
| +# CONFIG_MTD_NAND_TXX9NDFMC is not set
 | |
| +CONFIG_MTD_OF_PARTS=y
 | |
| +# CONFIG_MTD_ONENAND is not set
 | |
| +# CONFIG_MTD_OOPS is not set
 | |
| +# CONFIG_MTD_OTP is not set
 | |
| +# CONFIG_MTD_PARTITIONED_MASTER is not set
 | |
| +# CONFIG_MTD_PCI is not set
 | |
| +# CONFIG_MTD_PCMCIA is not set
 | |
| +# CONFIG_MTD_PHRAM is not set
 | |
| +# CONFIG_MTD_PHYSMAP is not set
 | |
| +# CONFIG_MTD_PHYSMAP_COMPAT is not set
 | |
| +# CONFIG_MTD_PHYSMAP_GEMINI is not set
 | |
| +# CONFIG_MTD_PHYSMAP_GPIO_ADDR is not set
 | |
| +CONFIG_MTD_PHYSMAP_OF=y
 | |
| +# CONFIG_MTD_PHYSMAP_OF_GEMINI is not set
 | |
| +# CONFIG_MTD_PHYSMAP_OF_VERSATILE is not set
 | |
| +# CONFIG_MTD_PHYSMAP_VERSATILE is not set
 | |
| +# CONFIG_MTD_PLATRAM is not set
 | |
| +# CONFIG_MTD_PMC551 is not set
 | |
| +# CONFIG_MTD_RAM is not set
 | |
| +# CONFIG_MTD_RAW_NAND is not set
 | |
| +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
 | |
| +# CONFIG_MTD_REDBOOT_PARTS is not set
 | |
| +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
 | |
| +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
 | |
| +# CONFIG_MTD_ROM is not set
 | |
| +CONFIG_MTD_ROOTFS_ROOT_DEV=y
 | |
| +# CONFIG_MTD_ROUTERBOOT_PARTS is not set
 | |
| +# CONFIG_MTD_SLRAM is not set
 | |
| +# CONFIG_MTD_SM_COMMON is not set
 | |
| +# CONFIG_MTD_SPINAND_MT29F is not set
 | |
| +# CONFIG_MTD_SPI_NAND is not set
 | |
| +# CONFIG_MTD_SPI_NOR is not set
 | |
| +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
 | |
| +CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096
 | |
| +CONFIG_MTD_SPLIT=y
 | |
| +# CONFIG_MTD_SPLIT_BCM63XX_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_BCM_WFI_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_ELF_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_EVA_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_FIRMWARE is not set
 | |
| +CONFIG_MTD_SPLIT_FIRMWARE_NAME="firmware"
 | |
| +# CONFIG_MTD_SPLIT_FIT_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_JIMAGE_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_LZMA_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_MINOR_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_SEAMA_FW is not set
 | |
| +CONFIG_MTD_SPLIT_SQUASHFS_ROOT=y
 | |
| +CONFIG_MTD_SPLIT_SUPPORT=y
 | |
| +# CONFIG_MTD_SPLIT_TPLINK_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_TRX_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_UIMAGE_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_WRGG_FW is not set
 | |
| +# CONFIG_MTD_SST25L is not set
 | |
| +# CONFIG_MTD_SWAP is not set
 | |
| +# CONFIG_MTD_TESTS is not set
 | |
| +# CONFIG_MTD_UBI is not set
 | |
| +# CONFIG_MTD_UBI_FASTMAP is not set
 | |
| +# CONFIG_MTD_UBI_GLUEBI is not set
 | |
| +# CONFIG_MTD_UIMAGE_SPLIT is not set
 | |
| +# CONFIG_MTD_VIRT_CONCAT is not set
 | |
| +# CONFIG_MTK_MMC is not set
 | |
| +# CONFIG_MTK_MMSYS is not set
 | |
| +CONFIG_MULTIUSER=y
 | |
| +# CONFIG_MUTEX_SPIN_ON_OWNER is not set
 | |
| +# CONFIG_MV643XX_ETH is not set
 | |
| +# CONFIG_MVMDIO is not set
 | |
| +# CONFIG_MVNETA_BM is not set
 | |
| +# CONFIG_MVSW61XX_PHY is not set
 | |
| +# CONFIG_MVSWITCH_PHY is not set
 | |
| +# CONFIG_MV_XOR_V2 is not set
 | |
| +# CONFIG_MWAVE is not set
 | |
| +# CONFIG_MWL8K is not set
 | |
| +# CONFIG_MXC4005 is not set
 | |
| +# CONFIG_MXC6255 is not set
 | |
| +# CONFIG_MYRI10GE is not set
 | |
| +# CONFIG_NAMESPACES is not set
 | |
| +# CONFIG_NATIONAL_PHY is not set
 | |
| +# CONFIG_NATSEMI is not set
 | |
| +# CONFIG_NAU7802 is not set
 | |
| +# CONFIG_NBPFAXI_DMA is not set
 | |
| +# CONFIG_NCP_FS is not set
 | |
| +# CONFIG_NE2000 is not set
 | |
| +# CONFIG_NE2K_PCI is not set
 | |
| +# CONFIG_NEC_MARKEINS is not set
 | |
| +CONFIG_NET=y
 | |
| +# CONFIG_NETCONSOLE is not set
 | |
| +CONFIG_NETDEVICES=y
 | |
| +# CONFIG_NETDEVSIM is not set
 | |
| +# CONFIG_NETFILTER is not set
 | |
| +# CONFIG_NETFILTER_ADVANCED is not set
 | |
| +# CONFIG_NETFILTER_DEBUG is not set
 | |
| +# CONFIG_NETFILTER_INGRESS is not set
 | |
| +# CONFIG_NETFILTER_NETLINK is not set
 | |
| +# CONFIG_NETFILTER_NETLINK_ACCT is not set
 | |
| +# CONFIG_NETFILTER_NETLINK_GLUE_CT is not set
 | |
| +# CONFIG_NETFILTER_NETLINK_LOG is not set
 | |
| +# CONFIG_NETFILTER_NETLINK_OSF is not set
 | |
| +# CONFIG_NETFILTER_NETLINK_QUEUE is not set
 | |
| +# CONFIG_NETFILTER_XTABLES is not set
 | |
| +# CONFIG_NETFILTER_XT_CONNMARK is not set
 | |
| +# CONFIG_NETFILTER_XT_MARK is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_BPF is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_CPU is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_ECN is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_ESP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_HL is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_MAC is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_MARK is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_NFACCT is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_OSF is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_REALM is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_STATE is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_STRING is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_TIME is not set
 | |
| +# CONFIG_NETFILTER_XT_MATCH_U32 is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_CT is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_HL is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_LED is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_LOG is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_MARK is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_NETMAP is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_SECMARK is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_TEE is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
 | |
| +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
 | |
| +# CONFIG_NETLABEL is not set
 | |
| +# CONFIG_NETLINK_DIAG is not set
 | |
| +# CONFIG_NETLINK_MMAP is not set
 | |
| +# CONFIG_NETPOLL is not set
 | |
| +# CONFIG_NETROM is not set
 | |
| +CONFIG_NETWORK_FILESYSTEMS=y
 | |
| +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
 | |
| +# CONFIG_NETWORK_SECMARK is not set
 | |
| +# CONFIG_NETXEN_NIC is not set
 | |
| +# CONFIG_NET_9P is not set
 | |
| +# CONFIG_NET_ACT_BPF is not set
 | |
| +# CONFIG_NET_ACT_CSUM is not set
 | |
| +# CONFIG_NET_ACT_CT is not set
 | |
| +# CONFIG_NET_ACT_GACT is not set
 | |
| +# CONFIG_NET_ACT_GATE is not set
 | |
| +# CONFIG_NET_ACT_IFE is not set
 | |
| +# CONFIG_NET_ACT_IPT is not set
 | |
| +# CONFIG_NET_ACT_MIRRED is not set
 | |
| +# CONFIG_NET_ACT_MPLS is not set
 | |
| +# CONFIG_NET_ACT_NAT is not set
 | |
| +# CONFIG_NET_ACT_PEDIT is not set
 | |
| +# CONFIG_NET_ACT_POLICE is not set
 | |
| +# CONFIG_NET_ACT_SAMPLE is not set
 | |
| +# CONFIG_NET_ACT_SIMP is not set
 | |
| +# CONFIG_NET_ACT_SKBEDIT is not set
 | |
| +# CONFIG_NET_ACT_SKBMOD is not set
 | |
| +# CONFIG_NET_ACT_TUNNEL_KEY is not set
 | |
| +# CONFIG_NET_ACT_VLAN is not set
 | |
| +CONFIG_NET_CADENCE=y
 | |
| +# CONFIG_NET_CALXEDA_XGMAC is not set
 | |
| +CONFIG_NET_CLS=y
 | |
| +# CONFIG_NET_CLS_ACT is not set
 | |
| +# CONFIG_NET_CLS_BASIC is not set
 | |
| +# CONFIG_NET_CLS_BPF is not set
 | |
| +# CONFIG_NET_CLS_FLOW is not set
 | |
| +# CONFIG_NET_CLS_FLOWER is not set
 | |
| +# CONFIG_NET_CLS_FW is not set
 | |
| +CONFIG_NET_CLS_IND=y
 | |
| +# CONFIG_NET_CLS_MATCHALL is not set
 | |
| +# CONFIG_NET_CLS_ROUTE4 is not set
 | |
| +# CONFIG_NET_CLS_RSVP is not set
 | |
| +# CONFIG_NET_CLS_RSVP6 is not set
 | |
| +# CONFIG_NET_CLS_TCINDEX is not set
 | |
| +# CONFIG_NET_CLS_U32 is not set
 | |
| +CONFIG_NET_CORE=y
 | |
| +# CONFIG_NET_DEVLINK is not set
 | |
| +# CONFIG_NET_DROP_MONITOR is not set
 | |
| +# CONFIG_NET_DSA is not set
 | |
| +# CONFIG_NET_DSA_AR9331 is not set
 | |
| +# CONFIG_NET_DSA_BCM_SF2 is not set
 | |
| +# CONFIG_NET_DSA_LANTIQ_GSWIP is not set
 | |
| +# CONFIG_NET_DSA_LEGACY is not set
 | |
| +# CONFIG_NET_DSA_LOOP is not set
 | |
| +# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set
 | |
| +# CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set
 | |
| +# CONFIG_NET_DSA_MSCC_SEVILLE is not set
 | |
| +# CONFIG_NET_DSA_MT7530 is not set
 | |
| +# CONFIG_NET_DSA_MV88E6060 is not set
 | |
| +# CONFIG_NET_DSA_MV88E6123_61_65 is not set
 | |
| +# CONFIG_NET_DSA_MV88E6131 is not set
 | |
| +# CONFIG_NET_DSA_MV88E6171 is not set
 | |
| +# CONFIG_NET_DSA_MV88E6352 is not set
 | |
| +# CONFIG_NET_DSA_MV88E6XXX is not set
 | |
| +# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
 | |
| +# CONFIG_NET_DSA_MV88E6XXX_PTP is not set
 | |
| +# CONFIG_NET_DSA_QCA8K is not set
 | |
| +# CONFIG_NET_DSA_REALTEK_SMI is not set
 | |
| +# CONFIG_NET_DSA_SJA1105 is not set
 | |
| +# CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set
 | |
| +# CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set
 | |
| +# CONFIG_NET_DSA_TAG_8021Q is not set
 | |
| +# CONFIG_NET_DSA_TAG_AR9331 is not set
 | |
| +# CONFIG_NET_DSA_TAG_BRCM is not set
 | |
| +# CONFIG_NET_DSA_TAG_BRCM_PREPEND is not set
 | |
| +# CONFIG_NET_DSA_TAG_DSA is not set
 | |
| +# CONFIG_NET_DSA_TAG_EDSA is not set
 | |
| +# CONFIG_NET_DSA_TAG_GSWIP is not set
 | |
| +# CONFIG_NET_DSA_TAG_KSZ is not set
 | |
| +# CONFIG_NET_DSA_TAG_LAN9303 is not set
 | |
| +# CONFIG_NET_DSA_TAG_MTK is not set
 | |
| +# CONFIG_NET_DSA_TAG_OCELOT is not set
 | |
| +# CONFIG_NET_DSA_TAG_QCA is not set
 | |
| +# CONFIG_NET_DSA_TAG_RTL4_A is not set
 | |
| +# CONFIG_NET_DSA_TAG_SJA1105 is not set
 | |
| +# CONFIG_NET_DSA_TAG_TRAILER is not set
 | |
| +# CONFIG_NET_DSA_VITESSE_VSC73XX is not set
 | |
| +# CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM is not set
 | |
| +# CONFIG_NET_DSA_VITESSE_VSC73XX_SPI is not set
 | |
| +# CONFIG_NET_EMATCH is not set
 | |
| +# CONFIG_NET_EMATCH_CANID is not set
 | |
| +# CONFIG_NET_EMATCH_CMP is not set
 | |
| +# CONFIG_NET_EMATCH_IPT is not set
 | |
| +# CONFIG_NET_EMATCH_META is not set
 | |
| +# CONFIG_NET_EMATCH_NBYTE is not set
 | |
| +CONFIG_NET_EMATCH_STACK=32
 | |
| +# CONFIG_NET_EMATCH_TEXT is not set
 | |
| +# CONFIG_NET_EMATCH_U32 is not set
 | |
| +# CONFIG_NET_FAILOVER is not set
 | |
| +# CONFIG_NET_FC is not set
 | |
| +# CONFIG_NET_FOU is not set
 | |
| +# CONFIG_NET_FOU_IP_TUNNELS is not set
 | |
| +# CONFIG_NET_IFE is not set
 | |
| +# CONFIG_NET_IPGRE is not set
 | |
| +CONFIG_NET_IPGRE_BROADCAST=y
 | |
| +# CONFIG_NET_IPGRE_DEMUX is not set
 | |
| +# CONFIG_NET_IPIP is not set
 | |
| +# CONFIG_NET_IPVTI is not set
 | |
| +# CONFIG_NET_IP_TUNNEL is not set
 | |
| +# CONFIG_NET_KEY is not set
 | |
| +# CONFIG_NET_KEY_MIGRATE is not set
 | |
| +# CONFIG_NET_L3_MASTER_DEV is not set
 | |
| +# CONFIG_NET_MEDIATEK_STAR_EMAC is not set
 | |
| +# CONFIG_NET_MPLS_GSO is not set
 | |
| +# CONFIG_NET_NCSI is not set
 | |
| +# CONFIG_NET_NSH is not set
 | |
| +# CONFIG_NET_PACKET_ENGINE is not set
 | |
| +# CONFIG_NET_PKTGEN is not set
 | |
| +# CONFIG_NET_POLL_CONTROLLER is not set
 | |
| +# CONFIG_NET_PTP_CLASSIFY is not set
 | |
| +CONFIG_NET_RX_BUSY_POLL=y
 | |
| +# CONFIG_NET_SB1000 is not set
 | |
| +CONFIG_NET_SCHED=y
 | |
| +# CONFIG_NET_SCH_ATM is not set
 | |
| +# CONFIG_NET_SCH_CAKE is not set
 | |
| +# CONFIG_NET_SCH_CBQ is not set
 | |
| +# CONFIG_NET_SCH_CBS is not set
 | |
| +# CONFIG_NET_SCH_CHOKE is not set
 | |
| +# CONFIG_NET_SCH_CODEL is not set
 | |
| +# CONFIG_NET_SCH_DEFAULT is not set
 | |
| +# CONFIG_NET_SCH_DRR is not set
 | |
| +# CONFIG_NET_SCH_DSMARK is not set
 | |
| +# CONFIG_NET_SCH_ETF is not set
 | |
| +# CONFIG_NET_SCH_ETS is not set
 | |
| +CONFIG_NET_SCH_FIFO=y
 | |
| +# CONFIG_NET_SCH_FQ is not set
 | |
| +CONFIG_NET_SCH_FQ_CODEL=y
 | |
| +# CONFIG_NET_SCH_FQ_PIE is not set
 | |
| +# CONFIG_NET_SCH_GRED is not set
 | |
| +# CONFIG_NET_SCH_HFSC is not set
 | |
| +# CONFIG_NET_SCH_HHF is not set
 | |
| +# CONFIG_NET_SCH_HTB is not set
 | |
| +# CONFIG_NET_SCH_INGRESS is not set
 | |
| +# CONFIG_NET_SCH_MQPRIO is not set
 | |
| +# CONFIG_NET_SCH_MULTIQ is not set
 | |
| +# CONFIG_NET_SCH_NETEM is not set
 | |
| +# CONFIG_NET_SCH_PIE is not set
 | |
| +# CONFIG_NET_SCH_PLUG is not set
 | |
| +# CONFIG_NET_SCH_PRIO is not set
 | |
| +# CONFIG_NET_SCH_QFQ is not set
 | |
| +# CONFIG_NET_SCH_RED is not set
 | |
| +# CONFIG_NET_SCH_SFB is not set
 | |
| +# CONFIG_NET_SCH_SFQ is not set
 | |
| +# CONFIG_NET_SCH_SKBPRIO is not set
 | |
| +# CONFIG_NET_SCH_TAPRIO is not set
 | |
| +# CONFIG_NET_SCH_TBF is not set
 | |
| +# CONFIG_NET_SCH_TEQL is not set
 | |
| +# CONFIG_NET_SCTPPROBE is not set
 | |
| +# CONFIG_NET_SWITCHDEV is not set
 | |
| +# CONFIG_NET_TCPPROBE is not set
 | |
| +# CONFIG_NET_TC_SKB_EXT is not set
 | |
| +# CONFIG_NET_TEAM is not set
 | |
| +# CONFIG_NET_TULIP is not set
 | |
| +# CONFIG_NET_UDP_TUNNEL is not set
 | |
| +CONFIG_NET_VENDOR_3COM=y
 | |
| +CONFIG_NET_VENDOR_8390=y
 | |
| +CONFIG_NET_VENDOR_ADAPTEC=y
 | |
| +CONFIG_NET_VENDOR_AGERE=y
 | |
| +CONFIG_NET_VENDOR_ALACRITECH=y
 | |
| +CONFIG_NET_VENDOR_ALTEON=y
 | |
| +CONFIG_NET_VENDOR_AMAZON=y
 | |
| +CONFIG_NET_VENDOR_AMD=y
 | |
| +CONFIG_NET_VENDOR_AQUANTIA=y
 | |
| +CONFIG_NET_VENDOR_ARC=y
 | |
| +CONFIG_NET_VENDOR_ATHEROS=y
 | |
| +CONFIG_NET_VENDOR_AURORA=y
 | |
| +CONFIG_NET_VENDOR_BROADCOM=y
 | |
| +CONFIG_NET_VENDOR_BROCADE=y
 | |
| +CONFIG_NET_VENDOR_CADENCE=y
 | |
| +CONFIG_NET_VENDOR_CAVIUM=y
 | |
| +CONFIG_NET_VENDOR_CHELSIO=y
 | |
| +CONFIG_NET_VENDOR_CIRRUS=y
 | |
| +CONFIG_NET_VENDOR_CISCO=y
 | |
| +CONFIG_NET_VENDOR_CORTINA=y
 | |
| +CONFIG_NET_VENDOR_DEC=y
 | |
| +CONFIG_NET_VENDOR_DLINK=y
 | |
| +CONFIG_NET_VENDOR_EMULEX=y
 | |
| +CONFIG_NET_VENDOR_EXAR=y
 | |
| +CONFIG_NET_VENDOR_EZCHIP=y
 | |
| +CONFIG_NET_VENDOR_FARADAY=y
 | |
| +CONFIG_NET_VENDOR_FREESCALE=y
 | |
| +CONFIG_NET_VENDOR_FUJITSU=y
 | |
| +CONFIG_NET_VENDOR_GOOGLE=y
 | |
| +CONFIG_NET_VENDOR_HISILICON=y
 | |
| +CONFIG_NET_VENDOR_HP=y
 | |
| +CONFIG_NET_VENDOR_HUAWEI=y
 | |
| +CONFIG_NET_VENDOR_I825XX=y
 | |
| +CONFIG_NET_VENDOR_IBM=y
 | |
| +CONFIG_NET_VENDOR_INTEL=y
 | |
| +CONFIG_NET_VENDOR_MARVELL=y
 | |
| +CONFIG_NET_VENDOR_MELLANOX=y
 | |
| +CONFIG_NET_VENDOR_MICREL=y
 | |
| +CONFIG_NET_VENDOR_MICROCHIP=y
 | |
| +CONFIG_NET_VENDOR_MICROSEMI=y
 | |
| +CONFIG_NET_VENDOR_MYRI=y
 | |
| +CONFIG_NET_VENDOR_NATSEMI=y
 | |
| +CONFIG_NET_VENDOR_NETERION=y
 | |
| +CONFIG_NET_VENDOR_NETRONOME=y
 | |
| +CONFIG_NET_VENDOR_NI=y
 | |
| +CONFIG_NET_VENDOR_NVIDIA=y
 | |
| +CONFIG_NET_VENDOR_OKI=y
 | |
| +CONFIG_NET_VENDOR_PACKET_ENGINES=y
 | |
| +CONFIG_NET_VENDOR_PENSANDO=y
 | |
| +CONFIG_NET_VENDOR_QLOGIC=y
 | |
| +CONFIG_NET_VENDOR_QUALCOMM=y
 | |
| +CONFIG_NET_VENDOR_RDC=y
 | |
| +CONFIG_NET_VENDOR_REALTEK=y
 | |
| +CONFIG_NET_VENDOR_RENESAS=y
 | |
| +CONFIG_NET_VENDOR_ROCKER=y
 | |
| +CONFIG_NET_VENDOR_SAMSUNG=y
 | |
| +CONFIG_NET_VENDOR_SEEQ=y
 | |
| +CONFIG_NET_VENDOR_SILAN=y
 | |
| +CONFIG_NET_VENDOR_SIS=y
 | |
| +CONFIG_NET_VENDOR_SMSC=y
 | |
| +CONFIG_NET_VENDOR_SOCIONEXT=y
 | |
| +CONFIG_NET_VENDOR_SOLARFLARE=y
 | |
| +CONFIG_NET_VENDOR_STMICRO=y
 | |
| +CONFIG_NET_VENDOR_SUN=y
 | |
| +CONFIG_NET_VENDOR_SYNOPSYS=y
 | |
| +CONFIG_NET_VENDOR_TEHUTI=y
 | |
| +CONFIG_NET_VENDOR_TI=y
 | |
| +CONFIG_NET_VENDOR_TOSHIBA=y
 | |
| +CONFIG_NET_VENDOR_VIA=y
 | |
| +CONFIG_NET_VENDOR_WIZNET=y
 | |
| +CONFIG_NET_VENDOR_XILINX=y
 | |
| +CONFIG_NET_VENDOR_XIRCOM=y
 | |
| +# CONFIG_NET_VRF is not set
 | |
| +# CONFIG_NET_XGENE is not set
 | |
| +CONFIG_NEW_LEDS=y
 | |
| +# CONFIG_NFC is not set
 | |
| +# CONFIG_NFP is not set
 | |
| +# CONFIG_NFSD is not set
 | |
| +# CONFIG_NFSD_V2_ACL is not set
 | |
| +CONFIG_NFSD_V3=y
 | |
| +# CONFIG_NFSD_V3_ACL is not set
 | |
| +# CONFIG_NFSD_V4 is not set
 | |
| +# CONFIG_NFS_ACL_SUPPORT is not set
 | |
| +CONFIG_NFS_COMMON=y
 | |
| +# CONFIG_NFS_DISABLE_UDP_SUPPORT is not set
 | |
| +# CONFIG_NFS_FS is not set
 | |
| +# CONFIG_NFS_FSCACHE is not set
 | |
| +# CONFIG_NFS_SWAP is not set
 | |
| +# CONFIG_NFS_V2 is not set
 | |
| +CONFIG_NFS_V3=y
 | |
| +# CONFIG_NFS_V3_ACL is not set
 | |
| +# CONFIG_NFS_V4 is not set
 | |
| +# CONFIG_NFS_V4_1 is not set
 | |
| +# CONFIG_NFTL is not set
 | |
| +# CONFIG_NFT_BRIDGE_META is not set
 | |
| +# CONFIG_NFT_BRIDGE_REJECT is not set
 | |
| +# CONFIG_NFT_CONNLIMIT is not set
 | |
| +# CONFIG_NFT_DUP_IPV4 is not set
 | |
| +# CONFIG_NFT_DUP_IPV6 is not set
 | |
| +# CONFIG_NFT_FIB_IPV4 is not set
 | |
| +# CONFIG_NFT_FIB_IPV6 is not set
 | |
| +# CONFIG_NFT_FIB_NETDEV is not set
 | |
| +# CONFIG_NFT_FLOW_OFFLOAD is not set
 | |
| +# CONFIG_NFT_OBJREF is not set
 | |
| +# CONFIG_NFT_OSF is not set
 | |
| +# CONFIG_NFT_RT is not set
 | |
| +# CONFIG_NFT_SET_BITMAP is not set
 | |
| +# CONFIG_NFT_SOCKET is not set
 | |
| +# CONFIG_NFT_SYNPROXY is not set
 | |
| +# CONFIG_NFT_TPROXY is not set
 | |
| +# CONFIG_NFT_TUNNEL is not set
 | |
| +# CONFIG_NFT_XFRM is not set
 | |
| +# CONFIG_NF_CONNTRACK is not set
 | |
| +# CONFIG_NF_CONNTRACK_AMANDA is not set
 | |
| +# CONFIG_NF_CONNTRACK_BRIDGE is not set
 | |
| +# CONFIG_NF_CONNTRACK_EVENTS is not set
 | |
| +# CONFIG_NF_CONNTRACK_FTP is not set
 | |
| +# CONFIG_NF_CONNTRACK_H323 is not set
 | |
| +# CONFIG_NF_CONNTRACK_IPV4 is not set
 | |
| +# CONFIG_NF_CONNTRACK_IPV6 is not set
 | |
| +# CONFIG_NF_CONNTRACK_IRC is not set
 | |
| +# CONFIG_NF_CONNTRACK_LABELS is not set
 | |
| +# CONFIG_NF_CONNTRACK_MARK is not set
 | |
| +# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
 | |
| +# CONFIG_NF_CONNTRACK_PPTP is not set
 | |
| +CONFIG_NF_CONNTRACK_PROCFS=y
 | |
| +# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
 | |
| +# CONFIG_NF_CONNTRACK_SANE is not set
 | |
| +# CONFIG_NF_CONNTRACK_SECMARK is not set
 | |
| +# CONFIG_NF_CONNTRACK_SIP is not set
 | |
| +# CONFIG_NF_CONNTRACK_SNMP is not set
 | |
| +# CONFIG_NF_CONNTRACK_TFTP is not set
 | |
| +# CONFIG_NF_CONNTRACK_TIMEOUT is not set
 | |
| +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
 | |
| +# CONFIG_NF_CONNTRACK_ZONES is not set
 | |
| +# CONFIG_NF_CT_NETLINK is not set
 | |
| +# CONFIG_NF_CT_NETLINK_HELPER is not set
 | |
| +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set
 | |
| +# CONFIG_NF_CT_PROTO_DCCP is not set
 | |
| +# CONFIG_NF_CT_PROTO_GRE is not set
 | |
| +# CONFIG_NF_CT_PROTO_SCTP is not set
 | |
| +# CONFIG_NF_CT_PROTO_UDPLITE is not set
 | |
| +# CONFIG_NF_DEFRAG_IPV4 is not set
 | |
| +# CONFIG_NF_DUP_IPV4 is not set
 | |
| +# CONFIG_NF_DUP_IPV6 is not set
 | |
| +# CONFIG_NF_FLOW_TABLE is not set
 | |
| +# CONFIG_NF_LOG_ARP is not set
 | |
| +# CONFIG_NF_LOG_BRIDGE is not set
 | |
| +# CONFIG_NF_LOG_IPV4 is not set
 | |
| +# CONFIG_NF_LOG_NETDEV is not set
 | |
| +# CONFIG_NF_NAT is not set
 | |
| +# CONFIG_NF_NAT_AMANDA is not set
 | |
| +# CONFIG_NF_NAT_FTP is not set
 | |
| +# CONFIG_NF_NAT_H323 is not set
 | |
| +# CONFIG_NF_NAT_IPV6 is not set
 | |
| +# CONFIG_NF_NAT_IRC is not set
 | |
| +CONFIG_NF_NAT_MASQUERADE_IPV4=y
 | |
| +CONFIG_NF_NAT_MASQUERADE_IPV6=y
 | |
| +# CONFIG_NF_NAT_NEEDED is not set
 | |
| +# CONFIG_NF_NAT_PPTP is not set
 | |
| +# CONFIG_NF_NAT_PROTO_GRE is not set
 | |
| +# CONFIG_NF_NAT_SIP is not set
 | |
| +# CONFIG_NF_NAT_SNMP_BASIC is not set
 | |
| +# CONFIG_NF_NAT_TFTP is not set
 | |
| +# CONFIG_NF_REJECT_IPV4 is not set
 | |
| +# CONFIG_NF_REJECT_IPV6 is not set
 | |
| +# CONFIG_NF_SOCKET_IPV4 is not set
 | |
| +# CONFIG_NF_SOCKET_IPV6 is not set
 | |
| +# CONFIG_NF_TABLES is not set
 | |
| +CONFIG_NF_TABLES_ARP=y
 | |
| +CONFIG_NF_TABLES_BRIDGE=y
 | |
| +CONFIG_NF_TABLES_INET=y
 | |
| +CONFIG_NF_TABLES_IPV4=y
 | |
| +CONFIG_NF_TABLES_IPV6=y
 | |
| +CONFIG_NF_TABLES_NETDEV=y
 | |
| +# CONFIG_NF_TABLES_SET is not set
 | |
| +# CONFIG_NF_TPROXY_IPV4 is not set
 | |
| +# CONFIG_NF_TPROXY_IPV6 is not set
 | |
| +# CONFIG_NI65 is not set
 | |
| +# CONFIG_NI903X_WDT is not set
 | |
| +# CONFIG_NIC7018_WDT is not set
 | |
| +# CONFIG_NILFS2_FS is not set
 | |
| +# CONFIG_NIU is not set
 | |
| +# CONFIG_NI_XGE_MANAGEMENT_ENET is not set
 | |
| +CONFIG_NLATTR=y
 | |
| +# CONFIG_NLMON is not set
 | |
| +# CONFIG_NLM_XLP_BOARD is not set
 | |
| +# CONFIG_NLM_XLR_BOARD is not set
 | |
| +# CONFIG_NLS is not set
 | |
| +# CONFIG_NLS_ASCII is not set
 | |
| +# CONFIG_NLS_CODEPAGE_1250 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_1251 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_437 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_737 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_775 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_850 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_852 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_855 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_857 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_860 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_861 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_862 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_863 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_864 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_865 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_866 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_869 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_874 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_932 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_936 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_949 is not set
 | |
| +# CONFIG_NLS_CODEPAGE_950 is not set
 | |
| +CONFIG_NLS_DEFAULT="iso8859-1"
 | |
| +# CONFIG_NLS_ISO8859_1 is not set
 | |
| +# CONFIG_NLS_ISO8859_13 is not set
 | |
| +# CONFIG_NLS_ISO8859_14 is not set
 | |
| +# CONFIG_NLS_ISO8859_15 is not set
 | |
| +# CONFIG_NLS_ISO8859_2 is not set
 | |
| +# CONFIG_NLS_ISO8859_3 is not set
 | |
| +# CONFIG_NLS_ISO8859_4 is not set
 | |
| +# CONFIG_NLS_ISO8859_5 is not set
 | |
| +# CONFIG_NLS_ISO8859_6 is not set
 | |
| +# CONFIG_NLS_ISO8859_7 is not set
 | |
| +# CONFIG_NLS_ISO8859_8 is not set
 | |
| +# CONFIG_NLS_ISO8859_9 is not set
 | |
| +# CONFIG_NLS_KOI8_R is not set
 | |
| +# CONFIG_NLS_KOI8_U is not set
 | |
| +# CONFIG_NLS_MAC_CELTIC is not set
 | |
| +# CONFIG_NLS_MAC_CENTEURO is not set
 | |
| +# CONFIG_NLS_MAC_CROATIAN is not set
 | |
| +# CONFIG_NLS_MAC_CYRILLIC is not set
 | |
| +# CONFIG_NLS_MAC_GAELIC is not set
 | |
| +# CONFIG_NLS_MAC_GREEK is not set
 | |
| +# CONFIG_NLS_MAC_ICELAND is not set
 | |
| +# CONFIG_NLS_MAC_INUIT is not set
 | |
| +# CONFIG_NLS_MAC_ROMAN is not set
 | |
| +# CONFIG_NLS_MAC_ROMANIAN is not set
 | |
| +# CONFIG_NLS_MAC_TURKISH is not set
 | |
| +# CONFIG_NLS_UTF8 is not set
 | |
| +CONFIG_NMI_LOG_BUF_SHIFT=13
 | |
| +# CONFIG_NOA1305 is not set
 | |
| +# CONFIG_NOP_USB_XCEIV is not set
 | |
| +# CONFIG_NORTEL_HERMES is not set
 | |
| +# CONFIG_NOTIFIER_ERROR_INJECTION is not set
 | |
| +# CONFIG_NOUVEAU_LEGACY_CTX_SUPPORT is not set
 | |
| +# CONFIG_NOZOMI is not set
 | |
| +# CONFIG_NO_BOOTMEM is not set
 | |
| +# CONFIG_NO_HZ is not set
 | |
| +# CONFIG_NO_HZ_FULL is not set
 | |
| +# CONFIG_NO_HZ_IDLE is not set
 | |
| +# CONFIG_NS83820 is not set
 | |
| +# CONFIG_NTB is not set
 | |
| +# CONFIG_NTFS_DEBUG is not set
 | |
| +# CONFIG_NTFS_FS is not set
 | |
| +# CONFIG_NTFS_RW is not set
 | |
| +# CONFIG_NTP_PPS is not set
 | |
| +# CONFIG_NULL_TTY is not set
 | |
| +# CONFIG_NUMA is not set
 | |
| +# CONFIG_NVM is not set
 | |
| +# CONFIG_NVMEM is not set
 | |
| +# CONFIG_NVMEM_BCM_OCOTP is not set
 | |
| +# CONFIG_NVMEM_IMX_OCOTP is not set
 | |
| +# CONFIG_NVMEM_REBOOT_MODE is not set
 | |
| +# CONFIG_NVMEM_SYSFS is not set
 | |
| +# CONFIG_NVME_FC is not set
 | |
| +# CONFIG_NVME_TARGET is not set
 | |
| +# CONFIG_NVRAM is not set
 | |
| +# CONFIG_NV_TCO is not set
 | |
| +# CONFIG_NXP_STB220 is not set
 | |
| +# CONFIG_NXP_STB225 is not set
 | |
| +# CONFIG_NXP_TJA11XX_PHY is not set
 | |
| +# CONFIG_N_GSM is not set
 | |
| +# CONFIG_OABI_COMPAT is not set
 | |
| +# CONFIG_OBS600 is not set
 | |
| +# CONFIG_OCFS2_FS is not set
 | |
| +# CONFIG_OCTEONTX2_AF is not set
 | |
| +# CONFIG_OCTEONTX2_PF is not set
 | |
| +# CONFIG_OF_OVERLAY is not set
 | |
| +CONFIG_OF_RESERVED_MEM=y
 | |
| +# CONFIG_OF_UNITTEST is not set
 | |
| +# CONFIG_OMAP2_DSS_DEBUG is not set
 | |
| +# CONFIG_OMAP2_DSS_DEBUGFS is not set
 | |
| +# CONFIG_OMAP2_DSS_SDI is not set
 | |
| +# CONFIG_OMAP_OCP2SCP is not set
 | |
| +# CONFIG_OMAP_USB2 is not set
 | |
| +# CONFIG_OMFS_FS is not set
 | |
| +# CONFIG_OPENVSWITCH is not set
 | |
| +# CONFIG_OPROFILE is not set
 | |
| +# CONFIG_OPROFILE_EVENT_MULTIPLEX is not set
 | |
| +# CONFIG_OPT3001 is not set
 | |
| +CONFIG_OPTIMIZE_INLINING=y
 | |
| +# CONFIG_ORANGEFS_FS is not set
 | |
| +# CONFIG_ORION_WATCHDOG is not set
 | |
| +# CONFIG_OSF_PARTITION is not set
 | |
| +CONFIG_OVERLAY_FS=y
 | |
| +# CONFIG_OVERLAY_FS_INDEX is not set
 | |
| +# CONFIG_OVERLAY_FS_METACOPY is not set
 | |
| +CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
 | |
| +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
 | |
| +CONFIG_OVERLAY_FS_XINO_AUTO=y
 | |
| +# CONFIG_OWL_LOADER is not set
 | |
| +# CONFIG_P54_COMMON is not set
 | |
| +# CONFIG_PA12203001 is not set
 | |
| +CONFIG_PACKET=y
 | |
| +# CONFIG_PACKET_DIAG is not set
 | |
| +# CONFIG_PACKING is not set
 | |
| +# CONFIG_PAGE_EXTENSION is not set
 | |
| +# CONFIG_PAGE_OWNER is not set
 | |
| +# CONFIG_PAGE_POISONING is not set
 | |
| +# CONFIG_PAGE_REPORTING is not set
 | |
| +# CONFIG_PAGE_SIZE_16KB is not set
 | |
| +# CONFIG_PAGE_SIZE_32KB is not set
 | |
| +CONFIG_PAGE_SIZE_4KB=y
 | |
| +# CONFIG_PAGE_SIZE_64KB is not set
 | |
| +# CONFIG_PAGE_SIZE_8KB is not set
 | |
| +# CONFIG_PALMAS_GPADC is not set
 | |
| +# CONFIG_PANASONIC_LAPTOP is not set
 | |
| +# CONFIG_PANEL is not set
 | |
| +CONFIG_PANIC_ON_OOPS=y
 | |
| +CONFIG_PANIC_ON_OOPS_VALUE=1
 | |
| +CONFIG_PANIC_TIMEOUT=1
 | |
| +# CONFIG_PANTHERLORD_FF is not set
 | |
| +# CONFIG_PARAVIRT is not set
 | |
| +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
 | |
| +# CONFIG_PARPORT is not set
 | |
| +# CONFIG_PARPORT_1284 is not set
 | |
| +# CONFIG_PARPORT_AX88796 is not set
 | |
| +# CONFIG_PARPORT_GSC is not set
 | |
| +# CONFIG_PARPORT_PC is not set
 | |
| +CONFIG_PARTITION_ADVANCED=y
 | |
| +# CONFIG_PATA_ALI is not set
 | |
| +# CONFIG_PATA_AMD is not set
 | |
| +# CONFIG_PATA_ARASAN_CF is not set
 | |
| +# CONFIG_PATA_ARTOP is not set
 | |
| +# CONFIG_PATA_ATIIXP is not set
 | |
| +# CONFIG_PATA_ATP867X is not set
 | |
| +# CONFIG_PATA_CMD640_PCI is not set
 | |
| +# CONFIG_PATA_CMD64X is not set
 | |
| +# CONFIG_PATA_CS5520 is not set
 | |
| +# CONFIG_PATA_CS5530 is not set
 | |
| +# CONFIG_PATA_CS5535 is not set
 | |
| +# CONFIG_PATA_CS5536 is not set
 | |
| +# CONFIG_PATA_CYPRESS is not set
 | |
| +# CONFIG_PATA_EFAR is not set
 | |
| +# CONFIG_PATA_HPT366 is not set
 | |
| +# CONFIG_PATA_HPT37X is not set
 | |
| +# CONFIG_PATA_HPT3X2N is not set
 | |
| +# CONFIG_PATA_HPT3X3 is not set
 | |
| +# CONFIG_PATA_IMX is not set
 | |
| +# CONFIG_PATA_ISAPNP is not set
 | |
| +# CONFIG_PATA_IT8213 is not set
 | |
| +# CONFIG_PATA_IT821X is not set
 | |
| +# CONFIG_PATA_JMICRON is not set
 | |
| +# CONFIG_PATA_LEGACY is not set
 | |
| +# CONFIG_PATA_MARVELL is not set
 | |
| +# CONFIG_PATA_MPIIX is not set
 | |
| +# CONFIG_PATA_NETCELL is not set
 | |
| +# CONFIG_PATA_NINJA32 is not set
 | |
| +# CONFIG_PATA_NS87410 is not set
 | |
| +# CONFIG_PATA_NS87415 is not set
 | |
| +# CONFIG_PATA_OCTEON_CF is not set
 | |
| +# CONFIG_PATA_OF_PLATFORM is not set
 | |
| +# CONFIG_PATA_OLDPIIX is not set
 | |
| +# CONFIG_PATA_OPTI is not set
 | |
| +# CONFIG_PATA_OPTIDMA is not set
 | |
| +# CONFIG_PATA_PCMCIA is not set
 | |
| +# CONFIG_PATA_PDC2027X is not set
 | |
| +# CONFIG_PATA_PDC_OLD is not set
 | |
| +# CONFIG_PATA_PLATFORM is not set
 | |
| +# CONFIG_PATA_QDI is not set
 | |
| +# CONFIG_PATA_RADISYS is not set
 | |
| +# CONFIG_PATA_RDC is not set
 | |
| +# CONFIG_PATA_RZ1000 is not set
 | |
| +# CONFIG_PATA_SC1200 is not set
 | |
| +# CONFIG_PATA_SCH is not set
 | |
| +# CONFIG_PATA_SERVERWORKS is not set
 | |
| +# CONFIG_PATA_SIL680 is not set
 | |
| +# CONFIG_PATA_SIS is not set
 | |
| +# CONFIG_PATA_TOSHIBA is not set
 | |
| +# CONFIG_PATA_TRIFLEX is not set
 | |
| +# CONFIG_PATA_VIA is not set
 | |
| +# CONFIG_PATA_WINBOND is not set
 | |
| +# CONFIG_PATA_WINBOND_VLB is not set
 | |
| +# CONFIG_PC104 is not set
 | |
| +# CONFIG_PC300TOO is not set
 | |
| +# CONFIG_PCCARD is not set
 | |
| +# CONFIG_PCH_DMA is not set
 | |
| +# CONFIG_PCH_GBE is not set
 | |
| +# CONFIG_PCH_PHUB is not set
 | |
| +# CONFIG_PCI is not set
 | |
| +# CONFIG_PCI200SYN is not set
 | |
| +# CONFIG_PCIEAER is not set
 | |
| +# CONFIG_PCIEAER_INJECT is not set
 | |
| +# CONFIG_PCIEASPM is not set
 | |
| +# CONFIG_PCIEPORTBUS is not set
 | |
| +# CONFIG_PCIE_AL is not set
 | |
| +# CONFIG_PCIE_ALTERA is not set
 | |
| +# CONFIG_PCIE_ARMADA_8K is not set
 | |
| +# CONFIG_PCIE_BUS_DEFAULT is not set
 | |
| +# CONFIG_PCIE_BUS_PEER2PEER is not set
 | |
| +CONFIG_PCIE_BUS_PERFORMANCE=y
 | |
| +# CONFIG_PCIE_BUS_SAFE is not set
 | |
| +# CONFIG_PCIE_BUS_TUNE_OFF is not set
 | |
| +# CONFIG_PCIE_BW is not set
 | |
| +# CONFIG_PCIE_CADENCE_HOST is not set
 | |
| +# CONFIG_PCIE_CADENCE_PLAT_HOST is not set
 | |
| +# CONFIG_PCIE_DPC is not set
 | |
| +# CONFIG_PCIE_DW_PLAT is not set
 | |
| +# CONFIG_PCIE_DW_PLAT_HOST is not set
 | |
| +# CONFIG_PCIE_ECRC is not set
 | |
| +# CONFIG_PCIE_IPROC is not set
 | |
| +# CONFIG_PCIE_KIRIN is not set
 | |
| +# CONFIG_PCIE_LAYERSCAPE_GEN4 is not set
 | |
| +# CONFIG_PCIE_PTM is not set
 | |
| +# CONFIG_PCIE_XILINX is not set
 | |
| +# CONFIG_PCIPCWATCHDOG is not set
 | |
| +# CONFIG_PCI_ATMEL is not set
 | |
| +# CONFIG_PCI_CNB20LE_QUIRK is not set
 | |
| +# CONFIG_PCI_DEBUG is not set
 | |
| +# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
 | |
| +# CONFIG_PCI_ENDPOINT is not set
 | |
| +# CONFIG_PCI_ENDPOINT_TEST is not set
 | |
| +# CONFIG_PCI_FTPCI100 is not set
 | |
| +# CONFIG_PCI_HERMES is not set
 | |
| +# CONFIG_PCI_HISI is not set
 | |
| +# CONFIG_PCI_HOST_GENERIC is not set
 | |
| +# CONFIG_PCI_HOST_THUNDER_ECAM is not set
 | |
| +# CONFIG_PCI_HOST_THUNDER_PEM is not set
 | |
| +# CONFIG_PCI_IOV is not set
 | |
| +# CONFIG_PCI_J721E_HOST is not set
 | |
| +# CONFIG_PCI_LAYERSCAPE is not set
 | |
| +# CONFIG_PCI_MESON is not set
 | |
| +# CONFIG_PCI_MSI is not set
 | |
| +# CONFIG_PCI_PASID is not set
 | |
| +# CONFIG_PCI_PF_STUB is not set
 | |
| +# CONFIG_PCI_PRI is not set
 | |
| +CONFIG_PCI_QUIRKS=y
 | |
| +# CONFIG_PCI_REALLOC_ENABLE_AUTO is not set
 | |
| +# CONFIG_PCI_STUB is not set
 | |
| +# CONFIG_PCI_SW_SWITCHTEC is not set
 | |
| +CONFIG_PCI_SYSCALL=y
 | |
| +# CONFIG_PCI_V3_SEMI is not set
 | |
| +# CONFIG_PCI_XGENE is not set
 | |
| +# CONFIG_PCMCIA is not set
 | |
| +# CONFIG_PCMCIA_3C574 is not set
 | |
| +# CONFIG_PCMCIA_3C589 is not set
 | |
| +# CONFIG_PCMCIA_AHA152X is not set
 | |
| +# CONFIG_PCMCIA_ATMEL is not set
 | |
| +# CONFIG_PCMCIA_AXNET is not set
 | |
| +# CONFIG_PCMCIA_DEBUG is not set
 | |
| +# CONFIG_PCMCIA_FDOMAIN is not set
 | |
| +# CONFIG_PCMCIA_FMVJ18X is not set
 | |
| +# CONFIG_PCMCIA_HERMES is not set
 | |
| +# CONFIG_PCMCIA_LOAD_CIS is not set
 | |
| +# CONFIG_PCMCIA_NINJA_SCSI is not set
 | |
| +# CONFIG_PCMCIA_NMCLAN is not set
 | |
| +# CONFIG_PCMCIA_PCNET is not set
 | |
| +# CONFIG_PCMCIA_QLOGIC is not set
 | |
| +# CONFIG_PCMCIA_RAYCS is not set
 | |
| +# CONFIG_PCMCIA_SMC91C92 is not set
 | |
| +# CONFIG_PCMCIA_SPECTRUM is not set
 | |
| +# CONFIG_PCMCIA_SYM53C500 is not set
 | |
| +# CONFIG_PCMCIA_WL3501 is not set
 | |
| +# CONFIG_PCMCIA_XIRC2PS is not set
 | |
| +# CONFIG_PCMCIA_XIRCOM is not set
 | |
| +# CONFIG_PCNET32 is not set
 | |
| +# CONFIG_PCSPKR_PLATFORM is not set
 | |
| +# CONFIG_PCS_XPCS is not set
 | |
| +# CONFIG_PD6729 is not set
 | |
| +# CONFIG_PDA_POWER is not set
 | |
| +# CONFIG_PDC_ADMA is not set
 | |
| +# CONFIG_PERCPU_STATS is not set
 | |
| +# CONFIG_PERCPU_TEST is not set
 | |
| +# CONFIG_PERF_EVENTS is not set
 | |
| +# CONFIG_PERF_EVENTS_AMD_POWER is not set
 | |
| +# CONFIG_PERSISTENT_KEYRINGS is not set
 | |
| +# CONFIG_PHANTOM is not set
 | |
| +# CONFIG_PHONET is not set
 | |
| +# CONFIG_PHYLIB is not set
 | |
| +# CONFIG_PHYS_ADDR_T_64BIT is not set
 | |
| +# CONFIG_PHY_CADENCE_DP is not set
 | |
| +# CONFIG_PHY_CADENCE_DPHY is not set
 | |
| +# CONFIG_PHY_CADENCE_SALVO is not set
 | |
| +# CONFIG_PHY_CADENCE_SIERRA is not set
 | |
| +# CONFIG_PHY_CADENCE_TORRENT is not set
 | |
| +# CONFIG_PHY_CPCAP_USB is not set
 | |
| +# CONFIG_PHY_EXYNOS_DP_VIDEO is not set
 | |
| +# CONFIG_PHY_EXYNOS_MIPI_VIDEO is not set
 | |
| +# CONFIG_PHY_FSL_IMX8MQ_USB is not set
 | |
| +# CONFIG_PHY_INTEL_KEEMBAY_EMMC is not set
 | |
| +# CONFIG_PHY_MAPPHONE_MDM6600 is not set
 | |
| +# CONFIG_PHY_MIXEL_MIPI_DPHY is not set
 | |
| +# CONFIG_PHY_MTK_HDMI is not set
 | |
| +# CONFIG_PHY_OCELOT_SERDES is not set
 | |
| +# CONFIG_PHY_PXA_28NM_HSIC is not set
 | |
| +# CONFIG_PHY_PXA_28NM_USB2 is not set
 | |
| +# CONFIG_PHY_QCOM_DWC3 is not set
 | |
| +# CONFIG_PHY_QCOM_USB_HS is not set
 | |
| +# CONFIG_PHY_QCOM_USB_HSIC is not set
 | |
| +# CONFIG_PHY_SAMSUNG_USB2 is not set
 | |
| +# CONFIG_PHY_TUSB1210 is not set
 | |
| +# CONFIG_PHY_XGENE is not set
 | |
| +# CONFIG_PI433 is not set
 | |
| +# CONFIG_PID_IN_CONTEXTIDR is not set
 | |
| +# CONFIG_PID_NS is not set
 | |
| +CONFIG_PINCONF=y
 | |
| +# CONFIG_PINCTRL is not set
 | |
| +# CONFIG_PINCTRL_AMD is not set
 | |
| +# CONFIG_PINCTRL_AXP209 is not set
 | |
| +# CONFIG_PINCTRL_CEDARFORK is not set
 | |
| +# CONFIG_PINCTRL_EXYNOS is not set
 | |
| +# CONFIG_PINCTRL_EXYNOS5440 is not set
 | |
| +# CONFIG_PINCTRL_ICELAKE is not set
 | |
| +# CONFIG_PINCTRL_INGENIC is not set
 | |
| +# CONFIG_PINCTRL_MCP23S08 is not set
 | |
| +# CONFIG_PINCTRL_MSM8X74 is not set
 | |
| +# CONFIG_PINCTRL_MT6779 is not set
 | |
| +# CONFIG_PINCTRL_MT8167 is not set
 | |
| +# CONFIG_PINCTRL_MT8192 is not set
 | |
| +# CONFIG_PINCTRL_MTK_V2 is not set
 | |
| +# CONFIG_PINCTRL_OCELOT is not set
 | |
| +CONFIG_PINCTRL_SINGLE=y
 | |
| +# CONFIG_PINCTRL_STMFX is not set
 | |
| +# CONFIG_PINCTRL_SX150X is not set
 | |
| +# CONFIG_PING is not set
 | |
| +CONFIG_PINMUX=y
 | |
| +# CONFIG_PKCS7_MESSAGE_PARSER is not set
 | |
| +# CONFIG_PL310_ERRATA_588369 is not set
 | |
| +# CONFIG_PL310_ERRATA_727915 is not set
 | |
| +# CONFIG_PL310_ERRATA_753970 is not set
 | |
| +# CONFIG_PL310_ERRATA_769419 is not set
 | |
| +# CONFIG_PL320_MBOX is not set
 | |
| +# CONFIG_PL330_DMA is not set
 | |
| +# CONFIG_PLATFORM_MHU is not set
 | |
| +# CONFIG_PLAT_SPEAR is not set
 | |
| +# CONFIG_PLIP is not set
 | |
| +# CONFIG_PLX_DMA is not set
 | |
| +# CONFIG_PLX_HERMES is not set
 | |
| +# CONFIG_PM is not set
 | |
| +# CONFIG_PMBUS is not set
 | |
| +# CONFIG_PMC_MSP is not set
 | |
| +# CONFIG_PMIC_ADP5520 is not set
 | |
| +# CONFIG_PMIC_DA903X is not set
 | |
| +# CONFIG_PMS7003 is not set
 | |
| +# CONFIG_PM_AUTOSLEEP is not set
 | |
| +# CONFIG_PM_DEBUG is not set
 | |
| +# CONFIG_PM_DEVFREQ is not set
 | |
| +# CONFIG_PM_WAKELOCKS is not set
 | |
| +# CONFIG_POSIX_MQUEUE is not set
 | |
| +CONFIG_POSIX_TIMERS=y
 | |
| +# CONFIG_POWERCAP is not set
 | |
| +# CONFIG_POWER_AVS is not set
 | |
| +# CONFIG_POWER_RESET is not set
 | |
| +# CONFIG_POWER_RESET_BRCMKONA is not set
 | |
| +# CONFIG_POWER_RESET_BRCMSTB is not set
 | |
| +# CONFIG_POWER_RESET_GPIO is not set
 | |
| +# CONFIG_POWER_RESET_GPIO_RESTART is not set
 | |
| +# CONFIG_POWER_RESET_LINKSTATION is not set
 | |
| +# CONFIG_POWER_RESET_LTC2952 is not set
 | |
| +# CONFIG_POWER_RESET_PIIX4_POWEROFF is not set
 | |
| +# CONFIG_POWER_RESET_RESTART is not set
 | |
| +# CONFIG_POWER_RESET_SYSCON is not set
 | |
| +# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
 | |
| +# CONFIG_POWER_RESET_VERSATILE is not set
 | |
| +# CONFIG_POWER_RESET_XGENE is not set
 | |
| +# CONFIG_POWER_SUPPLY is not set
 | |
| +# CONFIG_POWER_SUPPLY_DEBUG is not set
 | |
| +# CONFIG_POWER_SUPPLY_HWMON is not set
 | |
| +# CONFIG_PPC4xx_GPIO is not set
 | |
| +# CONFIG_PPC_16K_PAGES is not set
 | |
| +# CONFIG_PPC_256K_PAGES is not set
 | |
| +CONFIG_PPC_4K_PAGES=y
 | |
| +# CONFIG_PPC_64K_PAGES is not set
 | |
| +# CONFIG_PPC_DISABLE_WERROR is not set
 | |
| +# CONFIG_PPC_EMULATED_STATS is not set
 | |
| +# CONFIG_PPC_EPAPR_HV_BYTECHAN is not set
 | |
| +# CONFIG_PPP is not set
 | |
| +# CONFIG_PPPOATM is not set
 | |
| +# CONFIG_PPPOE is not set
 | |
| +# CONFIG_PPPOL2TP is not set
 | |
| +# CONFIG_PPP_ASYNC is not set
 | |
| +# CONFIG_PPP_BSDCOMP is not set
 | |
| +# CONFIG_PPP_DEFLATE is not set
 | |
| +CONFIG_PPP_FILTER=y
 | |
| +# CONFIG_PPP_MPPE is not set
 | |
| +CONFIG_PPP_MULTILINK=y
 | |
| +# CONFIG_PPP_SYNC_TTY is not set
 | |
| +# CONFIG_PPS is not set
 | |
| +# CONFIG_PPS_CLIENT_GPIO is not set
 | |
| +# CONFIG_PPS_CLIENT_KTIMER is not set
 | |
| +# CONFIG_PPS_CLIENT_LDISC is not set
 | |
| +# CONFIG_PPS_CLIENT_PARPORT is not set
 | |
| +# CONFIG_PPS_DEBUG is not set
 | |
| +# CONFIG_PPTP is not set
 | |
| +# CONFIG_PREEMPT is not set
 | |
| +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set
 | |
| +# CONFIG_PREEMPTIRQ_EVENTS is not set
 | |
| +CONFIG_PREEMPT_NONE=y
 | |
| +# CONFIG_PREEMPT_TRACER is not set
 | |
| +# CONFIG_PREEMPT_VOLUNTARY is not set
 | |
| +# CONFIG_PRESTERA is not set
 | |
| +CONFIG_PREVENT_FIRMWARE_BUILD=y
 | |
| +# CONFIG_PRIME_NUMBERS is not set
 | |
| +CONFIG_PRINTK=y
 | |
| +# CONFIG_PRINTK_CALLER is not set
 | |
| +CONFIG_PRINTK_NMI=y
 | |
| +CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
 | |
| +# CONFIG_PRINTK_TIME is not set
 | |
| +CONFIG_PRINT_STACK_DEPTH=64
 | |
| +# CONFIG_PRISM2_USB is not set
 | |
| +# CONFIG_PRISM54 is not set
 | |
| +# CONFIG_PROC_CHILDREN is not set
 | |
| +CONFIG_PROC_FS=y
 | |
| +# CONFIG_PROC_KCORE is not set
 | |
| +# CONFIG_PROC_PAGE_MONITOR is not set
 | |
| +# CONFIG_PROC_STRIPPED is not set
 | |
| +CONFIG_PROC_SYSCTL=y
 | |
| +# CONFIG_PROC_VMCORE_DEVICE_DUMP is not set
 | |
| +# CONFIG_PROFILE_ALL_BRANCHES is not set
 | |
| +# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
 | |
| +# CONFIG_PROFILING is not set
 | |
| +# CONFIG_PROVE_LOCKING is not set
 | |
| +# CONFIG_PROVE_RCU is not set
 | |
| +# CONFIG_PROVE_RCU_LIST is not set
 | |
| +# CONFIG_PROVE_RCU_REPEATEDLY is not set
 | |
| +# CONFIG_PSAMPLE is not set
 | |
| +# CONFIG_PSB6970_PHY is not set
 | |
| +# CONFIG_PSI is not set
 | |
| +# CONFIG_PSTORE is not set
 | |
| +# CONFIG_PTDUMP_DEBUGFS is not set
 | |
| +# CONFIG_PTP_1588_CLOCK is not set
 | |
| +# CONFIG_PTP_1588_CLOCK_IDT82P33 is not set
 | |
| +# CONFIG_PTP_1588_CLOCK_IDTCM is not set
 | |
| +# CONFIG_PTP_1588_CLOCK_IXP46X is not set
 | |
| +# CONFIG_PTP_1588_CLOCK_KVM is not set
 | |
| +# CONFIG_PTP_1588_CLOCK_PCH is not set
 | |
| +# CONFIG_PTP_1588_CLOCK_VMW is not set
 | |
| +# CONFIG_PUBLIC_KEY_ALGO_RSA is not set
 | |
| +# CONFIG_PVPANIC is not set
 | |
| +# CONFIG_PWM is not set
 | |
| +# CONFIG_PWM_DEBUG is not set
 | |
| +# CONFIG_PWM_FSL_FTM is not set
 | |
| +# CONFIG_PWM_PCA9685 is not set
 | |
| +CONFIG_PWRSEQ_EMMC=y
 | |
| +# CONFIG_PWRSEQ_SD8787 is not set
 | |
| +CONFIG_PWRSEQ_SIMPLE=y
 | |
| +# CONFIG_QCA7000 is not set
 | |
| +# CONFIG_QCA7000_SPI is not set
 | |
| +# CONFIG_QCA7000_UART is not set
 | |
| +# CONFIG_QCOM_EMAC is not set
 | |
| +# CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set
 | |
| +# CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set
 | |
| +# CONFIG_QCOM_FALKOR_ERRATUM_E1041 is not set
 | |
| +# CONFIG_QCOM_HIDMA is not set
 | |
| +# CONFIG_QCOM_HIDMA_MGMT is not set
 | |
| +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set
 | |
| +# CONFIG_QCOM_SPMI_ADC5 is not set
 | |
| +# CONFIG_QCOM_SPMI_IADC is not set
 | |
| +# CONFIG_QCOM_SPMI_TEMP_ALARM is not set
 | |
| +# CONFIG_QCOM_SPMI_VADC is not set
 | |
| +# CONFIG_QED is not set
 | |
| +# CONFIG_QLA3XXX is not set
 | |
| +# CONFIG_QLCNIC is not set
 | |
| +# CONFIG_QLGE is not set
 | |
| +# CONFIG_QNX4FS_FS is not set
 | |
| +# CONFIG_QNX6FS_FS is not set
 | |
| +# CONFIG_QORIQ_CPUFREQ is not set
 | |
| +# CONFIG_QORIQ_THERMAL is not set
 | |
| +# CONFIG_QRTR is not set
 | |
| +# CONFIG_QSEMI_PHY is not set
 | |
| +# CONFIG_QUEUED_LOCK_STAT is not set
 | |
| +# CONFIG_QUICC_ENGINE is not set
 | |
| +# CONFIG_QUOTA is not set
 | |
| +# CONFIG_QUOTACTL is not set
 | |
| +# CONFIG_QUOTA_DEBUG is not set
 | |
| +# CONFIG_R3964 is not set
 | |
| +# CONFIG_R6040 is not set
 | |
| +# CONFIG_R8169 is not set
 | |
| +# CONFIG_R8188EU is not set
 | |
| +# CONFIG_R8712U is not set
 | |
| +# CONFIG_R8723AU is not set
 | |
| +# CONFIG_RADIO_ADAPTERS is not set
 | |
| +# CONFIG_RADIO_AZTECH is not set
 | |
| +# CONFIG_RADIO_CADET is not set
 | |
| +# CONFIG_RADIO_GEMTEK is not set
 | |
| +# CONFIG_RADIO_MAXIRADIO is not set
 | |
| +# CONFIG_RADIO_RTRACK is not set
 | |
| +# CONFIG_RADIO_RTRACK2 is not set
 | |
| +# CONFIG_RADIO_SF16FMI is not set
 | |
| +# CONFIG_RADIO_SF16FMR2 is not set
 | |
| +# CONFIG_RADIO_TERRATEC is not set
 | |
| +# CONFIG_RADIO_TRUST is not set
 | |
| +# CONFIG_RADIO_TYPHOON is not set
 | |
| +# CONFIG_RADIO_ZOLTRIX is not set
 | |
| +# CONFIG_RAID6_PQ_BENCHMARK is not set
 | |
| +# CONFIG_RAID_ATTRS is not set
 | |
| +# CONFIG_RALINK is not set
 | |
| +# CONFIG_RANDOM32_SELFTEST is not set
 | |
| +# CONFIG_RANDOMIZE_BASE is not set
 | |
| +# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
 | |
| +# CONFIG_RANDOM_TRUST_CPU is not set
 | |
| +# CONFIG_RAPIDIO is not set
 | |
| +# CONFIG_RAS is not set
 | |
| +# CONFIG_RAW_DRIVER is not set
 | |
| +# CONFIG_RBTREE_TEST is not set
 | |
| +# CONFIG_RCU_BOOST is not set
 | |
| +CONFIG_RCU_CPU_STALL_TIMEOUT=60
 | |
| +# CONFIG_RCU_EQS_DEBUG is not set
 | |
| +# CONFIG_RCU_EXPEDITE_BOOT is not set
 | |
| +CONFIG_RCU_EXPERT=y
 | |
| +CONFIG_RCU_FANOUT=32
 | |
| +CONFIG_RCU_FANOUT_LEAF=16
 | |
| +# CONFIG_RCU_FAST_NO_HZ is not set
 | |
| +CONFIG_RCU_KTHREAD_PRIO=0
 | |
| +# CONFIG_RCU_NOCB_CPU is not set
 | |
| +# CONFIG_RCU_PERF_TEST is not set
 | |
| +# CONFIG_RCU_REF_SCALE_TEST is not set
 | |
| +# CONFIG_RCU_SCALE_TEST is not set
 | |
| +# CONFIG_RCU_STRICT_GRACE_PERIOD is not set
 | |
| +# CONFIG_RCU_TORTURE_TEST is not set
 | |
| +CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3
 | |
| +# CONFIG_RCU_TRACE is not set
 | |
| +# CONFIG_RC_ATI_REMOTE is not set
 | |
| +# CONFIG_RC_CORE is not set
 | |
| +# CONFIG_RC_DECODERS is not set
 | |
| +# CONFIG_RC_LOOPBACK is not set
 | |
| +# CONFIG_RC_MAP is not set
 | |
| +# CONFIG_RDS is not set
 | |
| +# CONFIG_RD_BZIP2 is not set
 | |
| +# CONFIG_RD_GZIP is not set
 | |
| +# CONFIG_RD_LZ4 is not set
 | |
| +# CONFIG_RD_LZMA is not set
 | |
| +# CONFIG_RD_LZO is not set
 | |
| +# CONFIG_RD_XZ is not set
 | |
| +# CONFIG_RD_ZSTD is not set
 | |
| +# CONFIG_READABLE_ASM is not set
 | |
| +# CONFIG_READ_ONLY_THP_FOR_FS is not set
 | |
| +# CONFIG_REALTEK_PHY is not set
 | |
| +# CONFIG_REDWOOD is not set
 | |
| +# CONFIG_REED_SOLOMON_TEST is not set
 | |
| +# CONFIG_REGMAP is not set
 | |
| +# CONFIG_REGMAP_I2C is not set
 | |
| +# CONFIG_REGMAP_MMIO is not set
 | |
| +# CONFIG_REGMAP_SPI is not set
 | |
| +# CONFIG_REGULATOR is not set
 | |
| +# CONFIG_REGULATOR_88PG86X is not set
 | |
| +# CONFIG_REGULATOR_ACT8865 is not set
 | |
| +# CONFIG_REGULATOR_AD5398 is not set
 | |
| +# CONFIG_REGULATOR_ANATOP is not set
 | |
| +# CONFIG_REGULATOR_DA9210 is not set
 | |
| +# CONFIG_REGULATOR_DA9211 is not set
 | |
| +# CONFIG_REGULATOR_DEBUG is not set
 | |
| +# CONFIG_REGULATOR_FAN53555 is not set
 | |
| +# CONFIG_REGULATOR_FAN53880 is not set
 | |
| +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
 | |
| +# CONFIG_REGULATOR_GPIO is not set
 | |
| +# CONFIG_REGULATOR_ISL6271A is not set
 | |
| +# CONFIG_REGULATOR_ISL9305 is not set
 | |
| +# CONFIG_REGULATOR_LP3971 is not set
 | |
| +# CONFIG_REGULATOR_LP3972 is not set
 | |
| +# CONFIG_REGULATOR_LP872X is not set
 | |
| +# CONFIG_REGULATOR_LP8755 is not set
 | |
| +# CONFIG_REGULATOR_LTC3589 is not set
 | |
| +# CONFIG_REGULATOR_LTC3676 is not set
 | |
| +# CONFIG_REGULATOR_MAX1586 is not set
 | |
| +# CONFIG_REGULATOR_MAX77620 is not set
 | |
| +# CONFIG_REGULATOR_MAX77826 is not set
 | |
| +# CONFIG_REGULATOR_MAX8649 is not set
 | |
| +# CONFIG_REGULATOR_MAX8660 is not set
 | |
| +# CONFIG_REGULATOR_MAX8952 is not set
 | |
| +# CONFIG_REGULATOR_MAX8973 is not set
 | |
| +# CONFIG_REGULATOR_MCP16502 is not set
 | |
| +# CONFIG_REGULATOR_MP5416 is not set
 | |
| +# CONFIG_REGULATOR_MP8859 is not set
 | |
| +# CONFIG_REGULATOR_MP886X is not set
 | |
| +# CONFIG_REGULATOR_MPQ7920 is not set
 | |
| +# CONFIG_REGULATOR_MT6311 is not set
 | |
| +# CONFIG_REGULATOR_PCA9450 is not set
 | |
| +# CONFIG_REGULATOR_PFUZE100 is not set
 | |
| +# CONFIG_REGULATOR_PV88060 is not set
 | |
| +# CONFIG_REGULATOR_PV88080 is not set
 | |
| +# CONFIG_REGULATOR_PV88090 is not set
 | |
| +# CONFIG_REGULATOR_PWM is not set
 | |
| +# CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY is not set
 | |
| +# CONFIG_REGULATOR_RT4801 is not set
 | |
| +# CONFIG_REGULATOR_RTMV20 is not set
 | |
| +# CONFIG_REGULATOR_SLG51000 is not set
 | |
| +# CONFIG_REGULATOR_SY8106A is not set
 | |
| +# CONFIG_REGULATOR_SY8824X is not set
 | |
| +# CONFIG_REGULATOR_SY8827N is not set
 | |
| +# CONFIG_REGULATOR_TI_ABB is not set
 | |
| +# CONFIG_REGULATOR_TPS51632 is not set
 | |
| +# CONFIG_REGULATOR_TPS62360 is not set
 | |
| +# CONFIG_REGULATOR_TPS65023 is not set
 | |
| +# CONFIG_REGULATOR_TPS6507X is not set
 | |
| +# CONFIG_REGULATOR_TPS65132 is not set
 | |
| +# CONFIG_REGULATOR_TPS6524X is not set
 | |
| +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
 | |
| +# CONFIG_REGULATOR_VCTRL is not set
 | |
| +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
 | |
| +# CONFIG_REISERFS_CHECK is not set
 | |
| +# CONFIG_REISERFS_FS is not set
 | |
| +# CONFIG_REISERFS_FS_POSIX_ACL is not set
 | |
| +# CONFIG_REISERFS_FS_SECURITY is not set
 | |
| +CONFIG_REISERFS_FS_XATTR=y
 | |
| +# CONFIG_REISERFS_PROC_INFO is not set
 | |
| +# CONFIG_RELAY is not set
 | |
| +# CONFIG_RELOCATABLE is not set
 | |
| +# CONFIG_REMOTEPROC is not set
 | |
| +# CONFIG_RENESAS_PHY is not set
 | |
| +# CONFIG_RESET_ATH79 is not set
 | |
| +# CONFIG_RESET_BERLIN is not set
 | |
| +# CONFIG_RESET_BRCMSTB_RESCAL is not set
 | |
| +# CONFIG_RESET_CONTROLLER is not set
 | |
| +# CONFIG_RESET_IMX7 is not set
 | |
| +# CONFIG_RESET_INTEL_GW is not set
 | |
| +# CONFIG_RESET_LANTIQ is not set
 | |
| +# CONFIG_RESET_LPC18XX is not set
 | |
| +# CONFIG_RESET_MESON is not set
 | |
| +# CONFIG_RESET_PISTACHIO is not set
 | |
| +# CONFIG_RESET_SOCFPGA is not set
 | |
| +# CONFIG_RESET_STM32 is not set
 | |
| +# CONFIG_RESET_SUNXI is not set
 | |
| +# CONFIG_RESET_TEGRA_BPMP is not set
 | |
| +# CONFIG_RESET_TI_SYSCON is not set
 | |
| +# CONFIG_RESET_ZYNQ is not set
 | |
| +# CONFIG_RFD77402 is not set
 | |
| +# CONFIG_RFD_FTL is not set
 | |
| +CONFIG_RFKILL=y
 | |
| +# CONFIG_RFKILL_FULL is not set
 | |
| +# CONFIG_RFKILL_GPIO is not set
 | |
| +# CONFIG_RFKILL_INPUT is not set
 | |
| +# CONFIG_RFKILL_LEDS is not set
 | |
| +# CONFIG_RFKILL_REGULATOR is not set
 | |
| +# CONFIG_RING_BUFFER_BENCHMARK is not set
 | |
| +# CONFIG_RING_BUFFER_STARTUP_TEST is not set
 | |
| +# CONFIG_RMI4_CORE is not set
 | |
| +# CONFIG_RMNET is not set
 | |
| +# CONFIG_ROCKCHIP_PHY is not set
 | |
| +# CONFIG_ROCKER is not set
 | |
| +# CONFIG_ROMFS_FS is not set
 | |
| +# CONFIG_ROSE is not set
 | |
| +# CONFIG_RPCSEC_GSS_KRB5 is not set
 | |
| +# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
 | |
| +# CONFIG_RPMSG_VIRTIO is not set
 | |
| +# CONFIG_RPR0521 is not set
 | |
| +# CONFIG_RSEQ is not set
 | |
| +# CONFIG_RT2X00 is not set
 | |
| +# CONFIG_RTC_CLASS is not set
 | |
| +# CONFIG_RTC_DEBUG is not set
 | |
| +# CONFIG_RTC_DRV_ABB5ZES3 is not set
 | |
| +# CONFIG_RTC_DRV_ABEOZ9 is not set
 | |
| +# CONFIG_RTC_DRV_ABX80X is not set
 | |
| +# CONFIG_RTC_DRV_ARMADA38X is not set
 | |
| +# CONFIG_RTC_DRV_AU1XXX is not set
 | |
| +# CONFIG_RTC_DRV_BQ32K is not set
 | |
| +# CONFIG_RTC_DRV_BQ4802 is not set
 | |
| +# CONFIG_RTC_DRV_CADENCE is not set
 | |
| +CONFIG_RTC_DRV_CMOS=y
 | |
| +# CONFIG_RTC_DRV_DS1286 is not set
 | |
| +# CONFIG_RTC_DRV_DS1302 is not set
 | |
| +# CONFIG_RTC_DRV_DS1305 is not set
 | |
| +# CONFIG_RTC_DRV_DS1307 is not set
 | |
| +# CONFIG_RTC_DRV_DS1307_CENTURY is not set
 | |
| +# CONFIG_RTC_DRV_DS1307_HWMON is not set
 | |
| +# CONFIG_RTC_DRV_DS1343 is not set
 | |
| +# CONFIG_RTC_DRV_DS1347 is not set
 | |
| +# CONFIG_RTC_DRV_DS1374 is not set
 | |
| +# CONFIG_RTC_DRV_DS1390 is not set
 | |
| +# CONFIG_RTC_DRV_DS1511 is not set
 | |
| +# CONFIG_RTC_DRV_DS1553 is not set
 | |
| +# CONFIG_RTC_DRV_DS1672 is not set
 | |
| +# CONFIG_RTC_DRV_DS1685_FAMILY is not set
 | |
| +# CONFIG_RTC_DRV_DS1742 is not set
 | |
| +# CONFIG_RTC_DRV_DS2404 is not set
 | |
| +# CONFIG_RTC_DRV_DS3232 is not set
 | |
| +# CONFIG_RTC_DRV_DS3234 is not set
 | |
| +# CONFIG_RTC_DRV_EM3027 is not set
 | |
| +# CONFIG_RTC_DRV_EP93XX is not set
 | |
| +# CONFIG_RTC_DRV_FM3130 is not set
 | |
| +# CONFIG_RTC_DRV_FTRTC010 is not set
 | |
| +# CONFIG_RTC_DRV_GENERIC is not set
 | |
| +# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
 | |
| +# CONFIG_RTC_DRV_HYM8563 is not set
 | |
| +# CONFIG_RTC_DRV_ISL12022 is not set
 | |
| +# CONFIG_RTC_DRV_ISL12026 is not set
 | |
| +# CONFIG_RTC_DRV_ISL12057 is not set
 | |
| +# CONFIG_RTC_DRV_ISL1208 is not set
 | |
| +# CONFIG_RTC_DRV_JZ4740 is not set
 | |
| +# CONFIG_RTC_DRV_M41T80 is not set
 | |
| +# CONFIG_RTC_DRV_M41T93 is not set
 | |
| +# CONFIG_RTC_DRV_M41T94 is not set
 | |
| +# CONFIG_RTC_DRV_M48T35 is not set
 | |
| +# CONFIG_RTC_DRV_M48T59 is not set
 | |
| +# CONFIG_RTC_DRV_M48T86 is not set
 | |
| +# CONFIG_RTC_DRV_MAX6900 is not set
 | |
| +# CONFIG_RTC_DRV_MAX6902 is not set
 | |
| +# CONFIG_RTC_DRV_MAX6916 is not set
 | |
| +# CONFIG_RTC_DRV_MCP795 is not set
 | |
| +# CONFIG_RTC_DRV_MOXART is not set
 | |
| +# CONFIG_RTC_DRV_MPC5121 is not set
 | |
| +# CONFIG_RTC_DRV_MSM6242 is not set
 | |
| +# CONFIG_RTC_DRV_MT2712 is not set
 | |
| +# CONFIG_RTC_DRV_OMAP is not set
 | |
| +# CONFIG_RTC_DRV_PCF2123 is not set
 | |
| +# CONFIG_RTC_DRV_PCF2127 is not set
 | |
| +# CONFIG_RTC_DRV_PCF85063 is not set
 | |
| +# CONFIG_RTC_DRV_PCF8523 is not set
 | |
| +# CONFIG_RTC_DRV_PCF85363 is not set
 | |
| +# CONFIG_RTC_DRV_PCF8563 is not set
 | |
| +# CONFIG_RTC_DRV_PCF8583 is not set
 | |
| +# CONFIG_RTC_DRV_PL030 is not set
 | |
| +# CONFIG_RTC_DRV_PL031 is not set
 | |
| +# CONFIG_RTC_DRV_PS3 is not set
 | |
| +# CONFIG_RTC_DRV_PT7C4338 is not set
 | |
| +# CONFIG_RTC_DRV_R7301 is not set
 | |
| +# CONFIG_RTC_DRV_R9701 is not set
 | |
| +# CONFIG_RTC_DRV_RP5C01 is not set
 | |
| +# CONFIG_RTC_DRV_RS5C348 is not set
 | |
| +# CONFIG_RTC_DRV_RS5C372 is not set
 | |
| +# CONFIG_RTC_DRV_RTC7301 is not set
 | |
| +# CONFIG_RTC_DRV_RV3028 is not set
 | |
| +# CONFIG_RTC_DRV_RV3029C2 is not set
 | |
| +# CONFIG_RTC_DRV_RV3032 is not set
 | |
| +# CONFIG_RTC_DRV_RV8803 is not set
 | |
| +# CONFIG_RTC_DRV_RX4581 is not set
 | |
| +# CONFIG_RTC_DRV_RX6110 is not set
 | |
| +# CONFIG_RTC_DRV_RX8010 is not set
 | |
| +# CONFIG_RTC_DRV_RX8025 is not set
 | |
| +# CONFIG_RTC_DRV_RX8581 is not set
 | |
| +# CONFIG_RTC_DRV_S35390A is not set
 | |
| +# CONFIG_RTC_DRV_SD3078 is not set
 | |
| +# CONFIG_RTC_DRV_SNVS is not set
 | |
| +# CONFIG_RTC_DRV_STK17TA8 is not set
 | |
| +# CONFIG_RTC_DRV_SUN6I is not set
 | |
| +# CONFIG_RTC_DRV_TEST is not set
 | |
| +# CONFIG_RTC_DRV_V3020 is not set
 | |
| +# CONFIG_RTC_DRV_X1205 is not set
 | |
| +# CONFIG_RTC_DRV_XGENE is not set
 | |
| +# CONFIG_RTC_DRV_ZYNQMP is not set
 | |
| +CONFIG_RTC_HCTOSYS=y
 | |
| +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
 | |
| +CONFIG_RTC_INTF_DEV=y
 | |
| +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
 | |
| +CONFIG_RTC_INTF_PROC=y
 | |
| +CONFIG_RTC_INTF_SYSFS=y
 | |
| +CONFIG_RTC_LIB=y
 | |
| +# CONFIG_RTC_NVMEM is not set
 | |
| +CONFIG_RTC_SYSTOHC=y
 | |
| +CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
 | |
| +# CONFIG_RTL8180 is not set
 | |
| +# CONFIG_RTL8187 is not set
 | |
| +# CONFIG_RTL8192E is not set
 | |
| +# CONFIG_RTL8192U is not set
 | |
| +# CONFIG_RTL8306_PHY is not set
 | |
| +# CONFIG_RTL8366RB_PHY is not set
 | |
| +# CONFIG_RTL8366S_PHY is not set
 | |
| +# CONFIG_RTL8366_SMI is not set
 | |
| +# CONFIG_RTL8366_SMI_DEBUG_FS is not set
 | |
| +# CONFIG_RTL8367B_PHY is not set
 | |
| +# CONFIG_RTL8367_PHY is not set
 | |
| +# CONFIG_RTLLIB is not set
 | |
| +# CONFIG_RTL_CARDS is not set
 | |
| +# CONFIG_RTS5208 is not set
 | |
| +CONFIG_RT_MUTEXES=y
 | |
| +# CONFIG_RUNTIME_DEBUG is not set
 | |
| +CONFIG_RUNTIME_TESTING_MENU=y
 | |
| +CONFIG_RWSEM_GENERIC_SPINLOCK=y
 | |
| +CONFIG_RXKAD=y
 | |
| +# CONFIG_S2IO is not set
 | |
| +# CONFIG_SAMPLES is not set
 | |
| +# CONFIG_SAMSUNG_LAPTOP is not set
 | |
| +# CONFIG_SATA_ACARD_AHCI is not set
 | |
| +# CONFIG_SATA_AHCI is not set
 | |
| +# CONFIG_SATA_AHCI_PLATFORM is not set
 | |
| +# CONFIG_SATA_DWC is not set
 | |
| +# CONFIG_SATA_FSL is not set
 | |
| +# CONFIG_SATA_HIGHBANK is not set
 | |
| +# CONFIG_SATA_HOST is not set
 | |
| +# CONFIG_SATA_INIC162X is not set
 | |
| +CONFIG_SATA_MOBILE_LPM_POLICY=0
 | |
| +# CONFIG_SATA_MV is not set
 | |
| +# CONFIG_SATA_NV is not set
 | |
| +# CONFIG_SATA_PMP is not set
 | |
| +# CONFIG_SATA_PROMISE is not set
 | |
| +# CONFIG_SATA_QSTOR is not set
 | |
| +# CONFIG_SATA_RCAR is not set
 | |
| +# CONFIG_SATA_SIL is not set
 | |
| +# CONFIG_SATA_SIL24 is not set
 | |
| +# CONFIG_SATA_SIS is not set
 | |
| +# CONFIG_SATA_SVW is not set
 | |
| +# CONFIG_SATA_SX4 is not set
 | |
| +# CONFIG_SATA_ULI is not set
 | |
| +# CONFIG_SATA_VIA is not set
 | |
| +# CONFIG_SATA_VITESSE is not set
 | |
| +# CONFIG_SBC_FITPC2_WATCHDOG is not set
 | |
| +CONFIG_SBITMAP=y
 | |
| +# CONFIG_SC92031 is not set
 | |
| +# CONFIG_SCA3000 is not set
 | |
| +# CONFIG_SCACHE_DEBUGFS is not set
 | |
| +# CONFIG_SCC is not set
 | |
| +# CONFIG_SCD30_CORE is not set
 | |
| +# CONFIG_SCF_TORTURE_TEST is not set
 | |
| +# CONFIG_SCHEDSTATS is not set
 | |
| +# CONFIG_SCHED_AUTOGROUP is not set
 | |
| +# CONFIG_SCHED_DEBUG is not set
 | |
| +CONFIG_SCHED_HRTICK=y
 | |
| +# CONFIG_SCHED_MC is not set
 | |
| +CONFIG_SCHED_OMIT_FRAME_POINTER=y
 | |
| +# CONFIG_SCHED_SMT is not set
 | |
| +# CONFIG_SCHED_STACK_END_CHECK is not set
 | |
| +# CONFIG_SCHED_TRACER is not set
 | |
| +# CONFIG_SCR24X is not set
 | |
| +# CONFIG_SCSI is not set
 | |
| +# CONFIG_SCSI_3W_9XXX is not set
 | |
| +# CONFIG_SCSI_3W_SAS is not set
 | |
| +# CONFIG_SCSI_7000FASST is not set
 | |
| +# CONFIG_SCSI_AACRAID is not set
 | |
| +# CONFIG_SCSI_ACARD is not set
 | |
| +# CONFIG_SCSI_ADVANSYS is not set
 | |
| +# CONFIG_SCSI_AHA152X is not set
 | |
| +# CONFIG_SCSI_AHA1542 is not set
 | |
| +# CONFIG_SCSI_AIC79XX is not set
 | |
| +# CONFIG_SCSI_AIC7XXX is not set
 | |
| +# CONFIG_SCSI_AIC94XX is not set
 | |
| +# CONFIG_SCSI_AM53C974 is not set
 | |
| +# CONFIG_SCSI_ARCMSR is not set
 | |
| +# CONFIG_SCSI_BFA_FC is not set
 | |
| +# CONFIG_SCSI_BNX2X_FCOE is not set
 | |
| +# CONFIG_SCSI_BNX2_ISCSI is not set
 | |
| +# CONFIG_SCSI_BUSLOGIC is not set
 | |
| +# CONFIG_SCSI_CHELSIO_FCOE is not set
 | |
| +# CONFIG_SCSI_CONSTANTS is not set
 | |
| +# CONFIG_SCSI_CXGB3_ISCSI is not set
 | |
| +# CONFIG_SCSI_CXGB4_ISCSI is not set
 | |
| +# CONFIG_SCSI_DC395x is not set
 | |
| +# CONFIG_SCSI_DEBUG is not set
 | |
| +# CONFIG_SCSI_DH is not set
 | |
| +CONFIG_SCSI_DMA=y
 | |
| +# CONFIG_SCSI_DMX3191D is not set
 | |
| +# CONFIG_SCSI_DPT_I2O is not set
 | |
| +# CONFIG_SCSI_DTC3280 is not set
 | |
| +# CONFIG_SCSI_EATA is not set
 | |
| +# CONFIG_SCSI_ESAS2R is not set
 | |
| +# CONFIG_SCSI_FC_ATTRS is not set
 | |
| +# CONFIG_SCSI_FDOMAIN_PCI is not set
 | |
| +# CONFIG_SCSI_FUTURE_DOMAIN is not set
 | |
| +# CONFIG_SCSI_GDTH is not set
 | |
| +# CONFIG_SCSI_GENERIC_NCR5380 is not set
 | |
| +# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 | |
| +# CONFIG_SCSI_HISI_SAS is not set
 | |
| +# CONFIG_SCSI_HPSA is not set
 | |
| +# CONFIG_SCSI_HPTIOP is not set
 | |
| +# CONFIG_SCSI_IN2000 is not set
 | |
| +# CONFIG_SCSI_INIA100 is not set
 | |
| +# CONFIG_SCSI_INITIO is not set
 | |
| +# CONFIG_SCSI_IPR is not set
 | |
| +# CONFIG_SCSI_IPS is not set
 | |
| +# CONFIG_SCSI_ISCI is not set
 | |
| +# CONFIG_SCSI_ISCSI_ATTRS is not set
 | |
| +# CONFIG_SCSI_LOGGING is not set
 | |
| +CONFIG_SCSI_LOWLEVEL=y
 | |
| +# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
 | |
| +# CONFIG_SCSI_LPFC is not set
 | |
| +CONFIG_SCSI_MOD=y
 | |
| +# CONFIG_SCSI_MPT2SAS is not set
 | |
| +# CONFIG_SCSI_MPT3SAS is not set
 | |
| +# CONFIG_SCSI_MQ_DEFAULT is not set
 | |
| +# CONFIG_SCSI_MVSAS is not set
 | |
| +# CONFIG_SCSI_MVSAS_DEBUG is not set
 | |
| +# CONFIG_SCSI_MVUMI is not set
 | |
| +# CONFIG_SCSI_MYRB is not set
 | |
| +# CONFIG_SCSI_MYRS is not set
 | |
| +# CONFIG_SCSI_NCR53C406A is not set
 | |
| +# CONFIG_SCSI_NETLINK is not set
 | |
| +# CONFIG_SCSI_NSP32 is not set
 | |
| +# CONFIG_SCSI_OSD_INITIATOR is not set
 | |
| +# CONFIG_SCSI_PAS16 is not set
 | |
| +# CONFIG_SCSI_PM8001 is not set
 | |
| +# CONFIG_SCSI_PMCRAID is not set
 | |
| +CONFIG_SCSI_PROC_FS=y
 | |
| +# CONFIG_SCSI_QLA_FC is not set
 | |
| +# CONFIG_SCSI_QLA_ISCSI is not set
 | |
| +# CONFIG_SCSI_QLOGIC_1280 is not set
 | |
| +# CONFIG_SCSI_QLOGIC_FAS is not set
 | |
| +# CONFIG_SCSI_SAS_ATTRS is not set
 | |
| +# CONFIG_SCSI_SAS_LIBSAS is not set
 | |
| +# CONFIG_SCSI_SCAN_ASYNC is not set
 | |
| +# CONFIG_SCSI_SMARTPQI is not set
 | |
| +# CONFIG_SCSI_SNIC is not set
 | |
| +# CONFIG_SCSI_SPI_ATTRS is not set
 | |
| +# CONFIG_SCSI_SRP_ATTRS is not set
 | |
| +# CONFIG_SCSI_STEX is not set
 | |
| +# CONFIG_SCSI_SYM53C416 is not set
 | |
| +# CONFIG_SCSI_SYM53C8XX_2 is not set
 | |
| +# CONFIG_SCSI_T128 is not set
 | |
| +# CONFIG_SCSI_U14_34F is not set
 | |
| +# CONFIG_SCSI_UFSHCD is not set
 | |
| +# CONFIG_SCSI_ULTRASTOR is not set
 | |
| +# CONFIG_SCSI_VIRTIO is not set
 | |
| +# CONFIG_SCSI_WD719X is not set
 | |
| +# CONFIG_SCx200_ACB is not set
 | |
| +# CONFIG_SDIO_UART is not set
 | |
| +# CONFIG_SDR_MAX2175 is not set
 | |
| +# CONFIG_SDR_PLATFORM_DRIVERS is not set
 | |
| +# CONFIG_SD_ADC_MODULATOR is not set
 | |
| +# CONFIG_SECCOMP is not set
 | |
| +CONFIG_SECTION_MISMATCH_WARN_ONLY=y
 | |
| +# CONFIG_SECURITY is not set
 | |
| +# CONFIG_SECURITYFS is not set
 | |
| +# CONFIG_SECURITY_APPARMOR is not set
 | |
| +CONFIG_SECURITY_DMESG_RESTRICT=y
 | |
| +# CONFIG_SECURITY_LOADPIN is not set
 | |
| +# CONFIG_SECURITY_LOCKDOWN_LSM is not set
 | |
| +# CONFIG_SECURITY_PATH is not set
 | |
| +# CONFIG_SECURITY_SAFESETID is not set
 | |
| +# CONFIG_SECURITY_SELINUX_AVC_STATS is not set
 | |
| +# CONFIG_SECURITY_SELINUX_BOOTPARAM is not set
 | |
| +CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=0
 | |
| +# CONFIG_SECURITY_SELINUX_DEVELOP is not set
 | |
| +# CONFIG_SECURITY_SELINUX_DISABLE is not set
 | |
| +# CONFIG_SECURITY_SMACK is not set
 | |
| +# CONFIG_SECURITY_TOMOYO is not set
 | |
| +# CONFIG_SECURITY_YAMA is not set
 | |
| +CONFIG_SELECT_MEMORY_MODEL=y
 | |
| +# CONFIG_SENSIRION_SGP30 is not set
 | |
| +# CONFIG_SENSORS_ABITUGURU is not set
 | |
| +# CONFIG_SENSORS_ABITUGURU3 is not set
 | |
| +# CONFIG_SENSORS_ACPI_POWER is not set
 | |
| +# CONFIG_SENSORS_AD7314 is not set
 | |
| +# CONFIG_SENSORS_AD7414 is not set
 | |
| +# CONFIG_SENSORS_AD7418 is not set
 | |
| +# CONFIG_SENSORS_ADC128D818 is not set
 | |
| +# CONFIG_SENSORS_ADCXX is not set
 | |
| +# CONFIG_SENSORS_ADM1021 is not set
 | |
| +# CONFIG_SENSORS_ADM1025 is not set
 | |
| +# CONFIG_SENSORS_ADM1026 is not set
 | |
| +# CONFIG_SENSORS_ADM1029 is not set
 | |
| +# CONFIG_SENSORS_ADM1031 is not set
 | |
| +# CONFIG_SENSORS_ADM1177 is not set
 | |
| +# CONFIG_SENSORS_ADM1266 is not set
 | |
| +# CONFIG_SENSORS_ADM1275 is not set
 | |
| +# CONFIG_SENSORS_ADM9240 is not set
 | |
| +# CONFIG_SENSORS_ADS1015 is not set
 | |
| +# CONFIG_SENSORS_ADS7828 is not set
 | |
| +# CONFIG_SENSORS_ADS7871 is not set
 | |
| +# CONFIG_SENSORS_ADT7310 is not set
 | |
| +# CONFIG_SENSORS_ADT7410 is not set
 | |
| +# CONFIG_SENSORS_ADT7411 is not set
 | |
| +# CONFIG_SENSORS_ADT7462 is not set
 | |
| +# CONFIG_SENSORS_ADT7470 is not set
 | |
| +# CONFIG_SENSORS_ADT7475 is not set
 | |
| +# CONFIG_SENSORS_AMC6821 is not set
 | |
| +# CONFIG_SENSORS_APDS990X is not set
 | |
| +# CONFIG_SENSORS_APPLESMC is not set
 | |
| +# CONFIG_SENSORS_AS370 is not set
 | |
| +# CONFIG_SENSORS_ASB100 is not set
 | |
| +# CONFIG_SENSORS_ASC7621 is not set
 | |
| +# CONFIG_SENSORS_ASPEED is not set
 | |
| +# CONFIG_SENSORS_ATK0110 is not set
 | |
| +# CONFIG_SENSORS_ATXP1 is not set
 | |
| +# CONFIG_SENSORS_AXI_FAN_CONTROL is not set
 | |
| +# CONFIG_SENSORS_BEL_PFE is not set
 | |
| +# CONFIG_SENSORS_BH1770 is not set
 | |
| +# CONFIG_SENSORS_BH1780 is not set
 | |
| +# CONFIG_SENSORS_CORETEMP is not set
 | |
| +# CONFIG_SENSORS_CORSAIR_CPRO is not set
 | |
| +# CONFIG_SENSORS_DELL_SMM is not set
 | |
| +# CONFIG_SENSORS_DME1737 is not set
 | |
| +# CONFIG_SENSORS_DRIVETEMP is not set
 | |
| +# CONFIG_SENSORS_DS1621 is not set
 | |
| +# CONFIG_SENSORS_DS620 is not set
 | |
| +# CONFIG_SENSORS_EMC1403 is not set
 | |
| +# CONFIG_SENSORS_EMC2103 is not set
 | |
| +# CONFIG_SENSORS_EMC6W201 is not set
 | |
| +# CONFIG_SENSORS_F71805F is not set
 | |
| +# CONFIG_SENSORS_F71882FG is not set
 | |
| +# CONFIG_SENSORS_F75375S is not set
 | |
| +# CONFIG_SENSORS_FAM15H_POWER is not set
 | |
| +# CONFIG_SENSORS_FSCHMD is not set
 | |
| +# CONFIG_SENSORS_FTSTEUTATES is not set
 | |
| +# CONFIG_SENSORS_G760A is not set
 | |
| +# CONFIG_SENSORS_G762 is not set
 | |
| +# CONFIG_SENSORS_GL518SM is not set
 | |
| +# CONFIG_SENSORS_GL520SM is not set
 | |
| +# CONFIG_SENSORS_GPIO_FAN is not set
 | |
| +# CONFIG_SENSORS_GSC is not set
 | |
| +# CONFIG_SENSORS_HDAPS is not set
 | |
| +# CONFIG_SENSORS_HIH6130 is not set
 | |
| +# CONFIG_SENSORS_HMC5843 is not set
 | |
| +# CONFIG_SENSORS_HMC5843_I2C is not set
 | |
| +# CONFIG_SENSORS_HMC5843_SPI is not set
 | |
| +# CONFIG_SENSORS_HTU21 is not set
 | |
| +# CONFIG_SENSORS_I5500 is not set
 | |
| +# CONFIG_SENSORS_I5K_AMB is not set
 | |
| +# CONFIG_SENSORS_IBM_CFFPS is not set
 | |
| +# CONFIG_SENSORS_IIO_HWMON is not set
 | |
| +# CONFIG_SENSORS_INA209 is not set
 | |
| +# CONFIG_SENSORS_INA2XX is not set
 | |
| +# CONFIG_SENSORS_INA3221 is not set
 | |
| +# CONFIG_SENSORS_INSPUR_IPSPS is not set
 | |
| +# CONFIG_SENSORS_IR35221 is not set
 | |
| +# CONFIG_SENSORS_IR38064 is not set
 | |
| +# CONFIG_SENSORS_IRPS5401 is not set
 | |
| +# CONFIG_SENSORS_ISL29018 is not set
 | |
| +# CONFIG_SENSORS_ISL29028 is not set
 | |
| +# CONFIG_SENSORS_ISL68137 is not set
 | |
| +# CONFIG_SENSORS_IT87 is not set
 | |
| +# CONFIG_SENSORS_JC42 is not set
 | |
| +# CONFIG_SENSORS_K10TEMP is not set
 | |
| +# CONFIG_SENSORS_K8TEMP is not set
 | |
| +# CONFIG_SENSORS_LINEAGE is not set
 | |
| +# CONFIG_SENSORS_LIS3LV02D is not set
 | |
| +# CONFIG_SENSORS_LIS3_I2C is not set
 | |
| +# CONFIG_SENSORS_LIS3_SPI is not set
 | |
| +# CONFIG_SENSORS_LM25066 is not set
 | |
| +# CONFIG_SENSORS_LM63 is not set
 | |
| +# CONFIG_SENSORS_LM70 is not set
 | |
| +# CONFIG_SENSORS_LM73 is not set
 | |
| +# CONFIG_SENSORS_LM75 is not set
 | |
| +# CONFIG_SENSORS_LM77 is not set
 | |
| +# CONFIG_SENSORS_LM78 is not set
 | |
| +# CONFIG_SENSORS_LM80 is not set
 | |
| +# CONFIG_SENSORS_LM83 is not set
 | |
| +# CONFIG_SENSORS_LM85 is not set
 | |
| +# CONFIG_SENSORS_LM87 is not set
 | |
| +# CONFIG_SENSORS_LM90 is not set
 | |
| +# CONFIG_SENSORS_LM92 is not set
 | |
| +# CONFIG_SENSORS_LM93 is not set
 | |
| +# CONFIG_SENSORS_LM95234 is not set
 | |
| +# CONFIG_SENSORS_LM95241 is not set
 | |
| +# CONFIG_SENSORS_LM95245 is not set
 | |
| +# CONFIG_SENSORS_LTC2945 is not set
 | |
| +# CONFIG_SENSORS_LTC2947_I2C is not set
 | |
| +# CONFIG_SENSORS_LTC2947_SPI is not set
 | |
| +# CONFIG_SENSORS_LTC2978 is not set
 | |
| +# CONFIG_SENSORS_LTC2990 is not set
 | |
| +# CONFIG_SENSORS_LTC3815 is not set
 | |
| +# CONFIG_SENSORS_LTC4151 is not set
 | |
| +# CONFIG_SENSORS_LTC4215 is not set
 | |
| +# CONFIG_SENSORS_LTC4222 is not set
 | |
| +# CONFIG_SENSORS_LTC4245 is not set
 | |
| +# CONFIG_SENSORS_LTC4260 is not set
 | |
| +# CONFIG_SENSORS_LTC4261 is not set
 | |
| +# CONFIG_SENSORS_LTQ_CPUTEMP is not set
 | |
| +# CONFIG_SENSORS_MAX1111 is not set
 | |
| +# CONFIG_SENSORS_MAX16064 is not set
 | |
| +# CONFIG_SENSORS_MAX16065 is not set
 | |
| +# CONFIG_SENSORS_MAX1619 is not set
 | |
| +# CONFIG_SENSORS_MAX16601 is not set
 | |
| +# CONFIG_SENSORS_MAX1668 is not set
 | |
| +# CONFIG_SENSORS_MAX197 is not set
 | |
| +# CONFIG_SENSORS_MAX20730 is not set
 | |
| +# CONFIG_SENSORS_MAX20751 is not set
 | |
| +# CONFIG_SENSORS_MAX31722 is not set
 | |
| +# CONFIG_SENSORS_MAX31730 is not set
 | |
| +# CONFIG_SENSORS_MAX31785 is not set
 | |
| +# CONFIG_SENSORS_MAX31790 is not set
 | |
| +# CONFIG_SENSORS_MAX34440 is not set
 | |
| +# CONFIG_SENSORS_MAX6621 is not set
 | |
| +# CONFIG_SENSORS_MAX6639 is not set
 | |
| +# CONFIG_SENSORS_MAX6642 is not set
 | |
| +# CONFIG_SENSORS_MAX6650 is not set
 | |
| +# CONFIG_SENSORS_MAX6697 is not set
 | |
| +# CONFIG_SENSORS_MAX8688 is not set
 | |
| +# CONFIG_SENSORS_MCP3021 is not set
 | |
| +# CONFIG_SENSORS_MP2975 is not set
 | |
| +# CONFIG_SENSORS_MR75203 is not set
 | |
| +# CONFIG_SENSORS_NCT6683 is not set
 | |
| +# CONFIG_SENSORS_NCT6775 is not set
 | |
| +# CONFIG_SENSORS_NCT7802 is not set
 | |
| +# CONFIG_SENSORS_NCT7904 is not set
 | |
| +# CONFIG_SENSORS_NPCM7XX is not set
 | |
| +# CONFIG_SENSORS_NSA320 is not set
 | |
| +# CONFIG_SENSORS_NTC_THERMISTOR is not set
 | |
| +# CONFIG_SENSORS_OCC_P8_I2C is not set
 | |
| +# CONFIG_SENSORS_PC87360 is not set
 | |
| +# CONFIG_SENSORS_PC87427 is not set
 | |
| +# CONFIG_SENSORS_PCF8591 is not set
 | |
| +# CONFIG_SENSORS_PMBUS is not set
 | |
| +# CONFIG_SENSORS_POWR1220 is not set
 | |
| +# CONFIG_SENSORS_PWM_FAN is not set
 | |
| +# CONFIG_SENSORS_PXE1610 is not set
 | |
| +# CONFIG_SENSORS_RM3100_I2C is not set
 | |
| +# CONFIG_SENSORS_RM3100_SPI is not set
 | |
| +# CONFIG_SENSORS_SCH5627 is not set
 | |
| +# CONFIG_SENSORS_SCH5636 is not set
 | |
| +# CONFIG_SENSORS_SCH56XX_COMMON is not set
 | |
| +# CONFIG_SENSORS_SHT15 is not set
 | |
| +# CONFIG_SENSORS_SHT21 is not set
 | |
| +# CONFIG_SENSORS_SHT3x is not set
 | |
| +# CONFIG_SENSORS_SHTC1 is not set
 | |
| +# CONFIG_SENSORS_SIS5595 is not set
 | |
| +# CONFIG_SENSORS_SMM665 is not set
 | |
| +# CONFIG_SENSORS_SMSC47B397 is not set
 | |
| +# CONFIG_SENSORS_SMSC47M1 is not set
 | |
| +# CONFIG_SENSORS_SMSC47M192 is not set
 | |
| +# CONFIG_SENSORS_STTS751 is not set
 | |
| +# CONFIG_SENSORS_TC654 is not set
 | |
| +# CONFIG_SENSORS_TC74 is not set
 | |
| +# CONFIG_SENSORS_THMC50 is not set
 | |
| +# CONFIG_SENSORS_TMP102 is not set
 | |
| +# CONFIG_SENSORS_TMP103 is not set
 | |
| +# CONFIG_SENSORS_TMP108 is not set
 | |
| +# CONFIG_SENSORS_TMP401 is not set
 | |
| +# CONFIG_SENSORS_TMP421 is not set
 | |
| +# CONFIG_SENSORS_TMP513 is not set
 | |
| +# CONFIG_SENSORS_TPS40422 is not set
 | |
| +# CONFIG_SENSORS_TPS53679 is not set
 | |
| +# CONFIG_SENSORS_TSL2550 is not set
 | |
| +# CONFIG_SENSORS_TSL2563 is not set
 | |
| +# CONFIG_SENSORS_UCD9000 is not set
 | |
| +# CONFIG_SENSORS_UCD9200 is not set
 | |
| +# CONFIG_SENSORS_VEXPRESS is not set
 | |
| +# CONFIG_SENSORS_VIA686A is not set
 | |
| +# CONFIG_SENSORS_VIA_CPUTEMP is not set
 | |
| +# CONFIG_SENSORS_VT1211 is not set
 | |
| +# CONFIG_SENSORS_VT8231 is not set
 | |
| +# CONFIG_SENSORS_W83627EHF is not set
 | |
| +# CONFIG_SENSORS_W83627HF is not set
 | |
| +# CONFIG_SENSORS_W83773G is not set
 | |
| +# CONFIG_SENSORS_W83781D is not set
 | |
| +# CONFIG_SENSORS_W83791D is not set
 | |
| +# CONFIG_SENSORS_W83792D is not set
 | |
| +# CONFIG_SENSORS_W83793 is not set
 | |
| +# CONFIG_SENSORS_W83795 is not set
 | |
| +# CONFIG_SENSORS_W83L785TS is not set
 | |
| +# CONFIG_SENSORS_W83L786NG is not set
 | |
| +# CONFIG_SENSORS_XDPE122 is not set
 | |
| +# CONFIG_SENSORS_XGENE is not set
 | |
| +# CONFIG_SENSORS_ZL6100 is not set
 | |
| +CONFIG_SERIAL_8250=y
 | |
| +# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
 | |
| +# CONFIG_SERIAL_8250_ACCENT is not set
 | |
| +# CONFIG_SERIAL_8250_ASPEED_VUART is not set
 | |
| +# CONFIG_SERIAL_8250_BOCA is not set
 | |
| +CONFIG_SERIAL_8250_CONSOLE=y
 | |
| +# CONFIG_SERIAL_8250_CS is not set
 | |
| +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
 | |
| +# CONFIG_SERIAL_8250_DETECT_IRQ is not set
 | |
| +CONFIG_SERIAL_8250_DMA=y
 | |
| +# CONFIG_SERIAL_8250_DW is not set
 | |
| +# CONFIG_SERIAL_8250_EM is not set
 | |
| +# CONFIG_SERIAL_8250_EXAR is not set
 | |
| +# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
 | |
| +# CONFIG_SERIAL_8250_EXTENDED is not set
 | |
| +# CONFIG_SERIAL_8250_FINTEK is not set
 | |
| +# CONFIG_SERIAL_8250_FOURPORT is not set
 | |
| +# CONFIG_SERIAL_8250_HUB6 is not set
 | |
| +# CONFIG_SERIAL_8250_INGENIC is not set
 | |
| +# CONFIG_SERIAL_8250_LPSS is not set
 | |
| +# CONFIG_SERIAL_8250_MANY_PORTS is not set
 | |
| +# CONFIG_SERIAL_8250_MID is not set
 | |
| +# CONFIG_SERIAL_8250_MOXA is not set
 | |
| +CONFIG_SERIAL_8250_NR_UARTS=2
 | |
| +# CONFIG_SERIAL_8250_PCI is not set
 | |
| +# CONFIG_SERIAL_8250_RSA is not set
 | |
| +# CONFIG_SERIAL_8250_RT288X is not set
 | |
| +CONFIG_SERIAL_8250_RUNTIME_UARTS=2
 | |
| +# CONFIG_SERIAL_ALTERA_JTAGUART is not set
 | |
| +# CONFIG_SERIAL_ALTERA_UART is not set
 | |
| +# CONFIG_SERIAL_AMBA_PL010 is not set
 | |
| +# CONFIG_SERIAL_AMBA_PL011 is not set
 | |
| +# CONFIG_SERIAL_ARC is not set
 | |
| +# CONFIG_SERIAL_BCM63XX is not set
 | |
| +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
 | |
| +CONFIG_SERIAL_CORE=y
 | |
| +CONFIG_SERIAL_CORE_CONSOLE=y
 | |
| +# CONFIG_SERIAL_DEV_BUS is not set
 | |
| +CONFIG_SERIAL_EARLYCON=y
 | |
| +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
 | |
| +# CONFIG_SERIAL_FSL_LINFLEXUART is not set
 | |
| +# CONFIG_SERIAL_FSL_LPUART is not set
 | |
| +# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
 | |
| +# CONFIG_SERIAL_IFX6X60 is not set
 | |
| +# CONFIG_SERIAL_JSM is not set
 | |
| +# CONFIG_SERIAL_MAX3100 is not set
 | |
| +# CONFIG_SERIAL_MAX310X is not set
 | |
| +# CONFIG_SERIAL_NONSTANDARD is not set
 | |
| +# CONFIG_SERIAL_OF_PLATFORM is not set
 | |
| +# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
 | |
| +# CONFIG_SERIAL_PCH_UART is not set
 | |
| +# CONFIG_SERIAL_RP2 is not set
 | |
| +# CONFIG_SERIAL_SC16IS7XX is not set
 | |
| +# CONFIG_SERIAL_SCCNXP is not set
 | |
| +# CONFIG_SERIAL_SH_SCI is not set
 | |
| +# CONFIG_SERIAL_SIFIVE is not set
 | |
| +# CONFIG_SERIAL_SPRD is not set
 | |
| +# CONFIG_SERIAL_STM32 is not set
 | |
| +# CONFIG_SERIAL_ST_ASC is not set
 | |
| +# CONFIG_SERIAL_TIMBERDALE is not set
 | |
| +# CONFIG_SERIAL_UARTLITE is not set
 | |
| +# CONFIG_SERIAL_XILINX_PS_UART is not set
 | |
| +# CONFIG_SERIO is not set
 | |
| +# CONFIG_SERIO_ALTERA_PS2 is not set
 | |
| +# CONFIG_SERIO_AMBAKMI is not set
 | |
| +# CONFIG_SERIO_APBPS2 is not set
 | |
| +# CONFIG_SERIO_ARC_PS2 is not set
 | |
| +# CONFIG_SERIO_CT82C710 is not set
 | |
| +# CONFIG_SERIO_GPIO_PS2 is not set
 | |
| +# CONFIG_SERIO_I8042 is not set
 | |
| +# CONFIG_SERIO_LIBPS2 is not set
 | |
| +# CONFIG_SERIO_PARKBD is not set
 | |
| +# CONFIG_SERIO_PCIPS2 is not set
 | |
| +# CONFIG_SERIO_PS2MULT is not set
 | |
| +# CONFIG_SERIO_RAW is not set
 | |
| +# CONFIG_SERIO_SERPORT is not set
 | |
| +# CONFIG_SERIO_SUN4I_PS2 is not set
 | |
| +# CONFIG_SFC is not set
 | |
| +# CONFIG_SFC_FALCON is not set
 | |
| +# CONFIG_SFI is not set
 | |
| +# CONFIG_SFP is not set
 | |
| +# CONFIG_SF_PDMA is not set
 | |
| +# CONFIG_SGETMASK_SYSCALL is not set
 | |
| +# CONFIG_SGI_IOC4 is not set
 | |
| +# CONFIG_SGI_IP22 is not set
 | |
| +# CONFIG_SGI_IP27 is not set
 | |
| +# CONFIG_SGI_IP28 is not set
 | |
| +# CONFIG_SGI_IP30 is not set
 | |
| +# CONFIG_SGI_IP32 is not set
 | |
| +# CONFIG_SGI_MFD_IOC3 is not set
 | |
| +# CONFIG_SGI_PARTITION is not set
 | |
| +# CONFIG_SG_POOL is not set
 | |
| +# CONFIG_SG_SPLIT is not set
 | |
| +CONFIG_SHMEM=y
 | |
| +# CONFIG_SHUFFLE_PAGE_ALLOCATOR is not set
 | |
| +# CONFIG_SH_ETH is not set
 | |
| +# CONFIG_SH_TIMER_CMT is not set
 | |
| +# CONFIG_SH_TIMER_MTU2 is not set
 | |
| +# CONFIG_SH_TIMER_TMU is not set
 | |
| +# CONFIG_SI1133 is not set
 | |
| +# CONFIG_SI1145 is not set
 | |
| +# CONFIG_SI7005 is not set
 | |
| +# CONFIG_SI7020 is not set
 | |
| +# CONFIG_SIBYTE_BIGSUR is not set
 | |
| +# CONFIG_SIBYTE_CARMEL is not set
 | |
| +# CONFIG_SIBYTE_CRHINE is not set
 | |
| +# CONFIG_SIBYTE_CRHONE is not set
 | |
| +# CONFIG_SIBYTE_LITTLESUR is not set
 | |
| +# CONFIG_SIBYTE_RHONE is not set
 | |
| +# CONFIG_SIBYTE_SENTOSA is not set
 | |
| +# CONFIG_SIBYTE_SWARM is not set
 | |
| +CONFIG_SIGNALFD=y
 | |
| +# CONFIG_SIGNED_PE_FILE_VERIFICATION is not set
 | |
| +# CONFIG_SIMPLE_GPIO is not set
 | |
| +# CONFIG_SIMPLE_PM_BUS is not set
 | |
| +# CONFIG_SIOX is not set
 | |
| +# CONFIG_SIS190 is not set
 | |
| +# CONFIG_SIS900 is not set
 | |
| +# CONFIG_SKGE is not set
 | |
| +# CONFIG_SKY2 is not set
 | |
| +# CONFIG_SKY2_DEBUG is not set
 | |
| +# CONFIG_SLAB is not set
 | |
| +CONFIG_SLABINFO=y
 | |
| +# CONFIG_SLAB_FREELIST_HARDENED is not set
 | |
| +# CONFIG_SLAB_FREELIST_RANDOM is not set
 | |
| +CONFIG_SLAB_MERGE_DEFAULT=y
 | |
| +# CONFIG_SLHC is not set
 | |
| +# CONFIG_SLICOSS is not set
 | |
| +# CONFIG_SLIMBUS is not set
 | |
| +# CONFIG_SLIP is not set
 | |
| +# CONFIG_SLOB is not set
 | |
| +CONFIG_SLUB=y
 | |
| +CONFIG_SLUB_CPU_PARTIAL=y
 | |
| +# CONFIG_SLUB_DEBUG is not set
 | |
| +# CONFIG_SLUB_DEBUG_ON is not set
 | |
| +# CONFIG_SLUB_MEMCG_SYSFS_ON is not set
 | |
| +# CONFIG_SLUB_STATS is not set
 | |
| +# CONFIG_SMARTJOYPLUS_FF is not set
 | |
| +# CONFIG_SMC911X is not set
 | |
| +# CONFIG_SMC9194 is not set
 | |
| +# CONFIG_SMC91X is not set
 | |
| +# CONFIG_SMP is not set
 | |
| +# CONFIG_SMSC911X is not set
 | |
| +# CONFIG_SMSC9420 is not set
 | |
| +# CONFIG_SMSC_PHY is not set
 | |
| +# CONFIG_SMS_SDIO_DRV is not set
 | |
| +# CONFIG_SMS_USB_DRV is not set
 | |
| +# CONFIG_SM_FTL is not set
 | |
| +# CONFIG_SND is not set
 | |
| +# CONFIG_SND_AC97_POWER_SAVE is not set
 | |
| +# CONFIG_SND_AD1816A is not set
 | |
| +# CONFIG_SND_AD1848 is not set
 | |
| +# CONFIG_SND_AD1889 is not set
 | |
| +# CONFIG_SND_ADLIB is not set
 | |
| +# CONFIG_SND_ALI5451 is not set
 | |
| +# CONFIG_SND_ALOOP is not set
 | |
| +# CONFIG_SND_ALS100 is not set
 | |
| +# CONFIG_SND_ALS300 is not set
 | |
| +# CONFIG_SND_ALS4000 is not set
 | |
| +# CONFIG_SND_ARM is not set
 | |
| +# CONFIG_SND_ASIHPI is not set
 | |
| +# CONFIG_SND_ATIIXP is not set
 | |
| +# CONFIG_SND_ATIIXP_MODEM is not set
 | |
| +# CONFIG_SND_ATMEL_AC97C is not set
 | |
| +# CONFIG_SND_ATMEL_SOC is not set
 | |
| +# CONFIG_SND_AU8810 is not set
 | |
| +# CONFIG_SND_AU8820 is not set
 | |
| +# CONFIG_SND_AU8830 is not set
 | |
| +# CONFIG_SND_AUDIO_GRAPH_CARD is not set
 | |
| +# CONFIG_SND_AUDIO_GRAPH_SCU_CARD is not set
 | |
| +# CONFIG_SND_AW2 is not set
 | |
| +# CONFIG_SND_AZT2320 is not set
 | |
| +# CONFIG_SND_AZT3328 is not set
 | |
| +# CONFIG_SND_BCD2000 is not set
 | |
| +# CONFIG_SND_BCM63XX_I2S_WHISTLER is not set
 | |
| +# CONFIG_SND_BT87X is not set
 | |
| +# CONFIG_SND_CA0106 is not set
 | |
| +# CONFIG_SND_CMI8330 is not set
 | |
| +# CONFIG_SND_CMIPCI is not set
 | |
| +# CONFIG_SND_CS4231 is not set
 | |
| +# CONFIG_SND_CS4236 is not set
 | |
| +# CONFIG_SND_CS4281 is not set
 | |
| +# CONFIG_SND_CS46XX is not set
 | |
| +# CONFIG_SND_CS5530 is not set
 | |
| +# CONFIG_SND_CS5535AUDIO is not set
 | |
| +# CONFIG_SND_CTXFI is not set
 | |
| +# CONFIG_SND_DARLA20 is not set
 | |
| +# CONFIG_SND_DARLA24 is not set
 | |
| +# CONFIG_SND_DEBUG is not set
 | |
| +# CONFIG_SND_DESIGNWARE_I2S is not set
 | |
| +CONFIG_SND_DRIVERS=y
 | |
| +# CONFIG_SND_DUMMY is not set
 | |
| +# CONFIG_SND_DYNAMIC_MINORS is not set
 | |
| +# CONFIG_SND_ECHO3G is not set
 | |
| +# CONFIG_SND_EDMA_SOC is not set
 | |
| +# CONFIG_SND_EMU10K1 is not set
 | |
| +# CONFIG_SND_EMU10K1X is not set
 | |
| +# CONFIG_SND_EMU10K1_SEQ is not set
 | |
| +# CONFIG_SND_ENS1370 is not set
 | |
| +# CONFIG_SND_ENS1371 is not set
 | |
| +# CONFIG_SND_ES1688 is not set
 | |
| +# CONFIG_SND_ES18XX is not set
 | |
| +# CONFIG_SND_ES1938 is not set
 | |
| +# CONFIG_SND_ES1968 is not set
 | |
| +# CONFIG_SND_FIREWIRE is not set
 | |
| +# CONFIG_SND_FM801 is not set
 | |
| +# CONFIG_SND_GINA20 is not set
 | |
| +# CONFIG_SND_GINA24 is not set
 | |
| +# CONFIG_SND_GUSCLASSIC is not set
 | |
| +# CONFIG_SND_GUSEXTREME is not set
 | |
| +# CONFIG_SND_GUSMAX is not set
 | |
| +# CONFIG_SND_HDA_INTEL is not set
 | |
| +# CONFIG_SND_HDA_INTEL_DETECT_DMIC is not set
 | |
| +# CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM is not set
 | |
| +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
 | |
| +CONFIG_SND_HDA_PREALLOC_SIZE=64
 | |
| +# CONFIG_SND_HDSP is not set
 | |
| +# CONFIG_SND_HDSPM is not set
 | |
| +# CONFIG_SND_HRTIMER is not set
 | |
| +# CONFIG_SND_HWDEP is not set
 | |
| +# CONFIG_SND_I2S_HI6210_I2S is not set
 | |
| +# CONFIG_SND_ICE1712 is not set
 | |
| +# CONFIG_SND_ICE1724 is not set
 | |
| +# CONFIG_SND_INDIGO is not set
 | |
| +# CONFIG_SND_INDIGODJ is not set
 | |
| +# CONFIG_SND_INDIGODJX is not set
 | |
| +# CONFIG_SND_INDIGOIO is not set
 | |
| +# CONFIG_SND_INDIGOIOX is not set
 | |
| +# CONFIG_SND_INTEL8X0 is not set
 | |
| +# CONFIG_SND_INTEL8X0M is not set
 | |
| +# CONFIG_SND_INTERWAVE is not set
 | |
| +# CONFIG_SND_INTERWAVE_STB is not set
 | |
| +# CONFIG_SND_ISA is not set
 | |
| +# CONFIG_SND_JZ4740_SOC_I2S is not set
 | |
| +# CONFIG_SND_KIRKWOOD_SOC is not set
 | |
| +# CONFIG_SND_KORG1212 is not set
 | |
| +# CONFIG_SND_LAYLA20 is not set
 | |
| +# CONFIG_SND_LAYLA24 is not set
 | |
| +# CONFIG_SND_LOLA is not set
 | |
| +# CONFIG_SND_LX6464ES is not set
 | |
| +# CONFIG_SND_MAESTRO3 is not set
 | |
| +CONFIG_SND_MAX_CARDS=16
 | |
| +# CONFIG_SND_MIA is not set
 | |
| +# CONFIG_SND_MIPS is not set
 | |
| +# CONFIG_SND_MIRO is not set
 | |
| +# CONFIG_SND_MIXART is not set
 | |
| +# CONFIG_SND_MIXER_OSS is not set
 | |
| +# CONFIG_SND_MONA is not set
 | |
| +# CONFIG_SND_MPC52xx_SOC_EFIKA is not set
 | |
| +# CONFIG_SND_MPU401 is not set
 | |
| +# CONFIG_SND_MTPAV is not set
 | |
| +# CONFIG_SND_MTS64 is not set
 | |
| +# CONFIG_SND_MXS_SOC is not set
 | |
| +# CONFIG_SND_NM256 is not set
 | |
| +# CONFIG_SND_OPL3SA2 is not set
 | |
| +# CONFIG_SND_OPL3_LIB_SEQ is not set
 | |
| +# CONFIG_SND_OPL4_LIB_SEQ is not set
 | |
| +# CONFIG_SND_OPTI92X_AD1848 is not set
 | |
| +# CONFIG_SND_OPTI92X_CS4231 is not set
 | |
| +# CONFIG_SND_OPTI93X is not set
 | |
| +CONFIG_SND_OSSEMUL=y
 | |
| +# CONFIG_SND_OXYGEN is not set
 | |
| +CONFIG_SND_PCI=y
 | |
| +# CONFIG_SND_PCM is not set
 | |
| +# CONFIG_SND_PCMCIA is not set
 | |
| +# CONFIG_SND_PCM_OSS is not set
 | |
| +CONFIG_SND_PCM_OSS_PLUGINS=y
 | |
| +# CONFIG_SND_PCM_TIMER is not set
 | |
| +# CONFIG_SND_PCM_XRUN_DEBUG is not set
 | |
| +# CONFIG_SND_PCXHR is not set
 | |
| +# CONFIG_SND_PDAUDIOCF is not set
 | |
| +# CONFIG_SND_PORTMAN2X4 is not set
 | |
| +# CONFIG_SND_POWERPC_SOC is not set
 | |
| +# CONFIG_SND_PPC is not set
 | |
| +CONFIG_SND_PROC_FS=y
 | |
| +# CONFIG_SND_RAWMIDI is not set
 | |
| +# CONFIG_SND_RAWMIDI_SEQ is not set
 | |
| +# CONFIG_SND_RIPTIDE is not set
 | |
| +# CONFIG_SND_RME32 is not set
 | |
| +# CONFIG_SND_RME96 is not set
 | |
| +# CONFIG_SND_RME9652 is not set
 | |
| +# CONFIG_SND_RTCTIMER is not set
 | |
| +# CONFIG_SND_SB16 is not set
 | |
| +# CONFIG_SND_SB8 is not set
 | |
| +# CONFIG_SND_SBAWE is not set
 | |
| +# CONFIG_SND_SBAWE_SEQ is not set
 | |
| +# CONFIG_SND_SE6X is not set
 | |
| +# CONFIG_SND_SEQUENCER is not set
 | |
| +# CONFIG_SND_SERIAL_U16550 is not set
 | |
| +# CONFIG_SND_SIMPLE_CARD is not set
 | |
| +# CONFIG_SND_SIMPLE_SCU_CARD is not set
 | |
| +# CONFIG_SND_SIS7019 is not set
 | |
| +# CONFIG_SND_SOC is not set
 | |
| +# CONFIG_SND_SOC_AC97_CODEC is not set
 | |
| +# CONFIG_SND_SOC_ADAU1701 is not set
 | |
| +# CONFIG_SND_SOC_ADAU1761_I2C is not set
 | |
| +# CONFIG_SND_SOC_ADAU1761_SPI is not set
 | |
| +# CONFIG_SND_SOC_ADAU7002 is not set
 | |
| +# CONFIG_SND_SOC_ADAU7118_HW is not set
 | |
| +# CONFIG_SND_SOC_ADAU7118_I2C is not set
 | |
| +# CONFIG_SND_SOC_AK4104 is not set
 | |
| +# CONFIG_SND_SOC_AK4118 is not set
 | |
| +# CONFIG_SND_SOC_AK4458 is not set
 | |
| +# CONFIG_SND_SOC_AK4554 is not set
 | |
| +# CONFIG_SND_SOC_AK4613 is not set
 | |
| +# CONFIG_SND_SOC_AK4642 is not set
 | |
| +# CONFIG_SND_SOC_AK5386 is not set
 | |
| +# CONFIG_SND_SOC_AK5558 is not set
 | |
| +# CONFIG_SND_SOC_ALC5623 is not set
 | |
| +# CONFIG_SND_SOC_AMD_ACP is not set
 | |
| +# CONFIG_SND_SOC_AMD_ACP3x is not set
 | |
| +# CONFIG_SND_SOC_AMD_RENOIR is not set
 | |
| +# CONFIG_SND_SOC_AU1XAUDIO is not set
 | |
| +# CONFIG_SND_SOC_AU1XPSC is not set
 | |
| +# CONFIG_SND_SOC_BD28623 is not set
 | |
| +# CONFIG_SND_SOC_BT_SCO is not set
 | |
| +# CONFIG_SND_SOC_CS35L32 is not set
 | |
| +# CONFIG_SND_SOC_CS35L33 is not set
 | |
| +# CONFIG_SND_SOC_CS35L34 is not set
 | |
| +# CONFIG_SND_SOC_CS35L35 is not set
 | |
| +# CONFIG_SND_SOC_CS35L36 is not set
 | |
| +# CONFIG_SND_SOC_CS4234 is not set
 | |
| +# CONFIG_SND_SOC_CS4265 is not set
 | |
| +# CONFIG_SND_SOC_CS4270 is not set
 | |
| +# CONFIG_SND_SOC_CS4271 is not set
 | |
| +# CONFIG_SND_SOC_CS4271_I2C is not set
 | |
| +# CONFIG_SND_SOC_CS4271_SPI is not set
 | |
| +# CONFIG_SND_SOC_CS42L42 is not set
 | |
| +# CONFIG_SND_SOC_CS42L51_I2C is not set
 | |
| +# CONFIG_SND_SOC_CS42L52 is not set
 | |
| +# CONFIG_SND_SOC_CS42L56 is not set
 | |
| +# CONFIG_SND_SOC_CS42L73 is not set
 | |
| +# CONFIG_SND_SOC_CS42XX8_I2C is not set
 | |
| +# CONFIG_SND_SOC_CS43130 is not set
 | |
| +# CONFIG_SND_SOC_CS4341 is not set
 | |
| +# CONFIG_SND_SOC_CS4349 is not set
 | |
| +# CONFIG_SND_SOC_CS53L30 is not set
 | |
| +# CONFIG_SND_SOC_CX2072X is not set
 | |
| +# CONFIG_SND_SOC_DA7213 is not set
 | |
| +# CONFIG_SND_SOC_DIO2125 is not set
 | |
| +# CONFIG_SND_SOC_DMIC is not set
 | |
| +# CONFIG_SND_SOC_ES7134 is not set
 | |
| +# CONFIG_SND_SOC_ES7241 is not set
 | |
| +# CONFIG_SND_SOC_ES8316 is not set
 | |
| +# CONFIG_SND_SOC_ES8328 is not set
 | |
| +# CONFIG_SND_SOC_ES8328_I2C is not set
 | |
| +# CONFIG_SND_SOC_ES8328_SPI is not set
 | |
| +# CONFIG_SND_SOC_EUKREA_TLV320 is not set
 | |
| +# CONFIG_SND_SOC_FSL_ASOC_CARD is not set
 | |
| +# CONFIG_SND_SOC_FSL_ASRC is not set
 | |
| +# CONFIG_SND_SOC_FSL_AUDMIX is not set
 | |
| +# CONFIG_SND_SOC_FSL_ESAI is not set
 | |
| +# CONFIG_SND_SOC_FSL_MICFIL is not set
 | |
| +# CONFIG_SND_SOC_FSL_SAI is not set
 | |
| +# CONFIG_SND_SOC_FSL_SPDIF is not set
 | |
| +# CONFIG_SND_SOC_FSL_SSI is not set
 | |
| +# CONFIG_SND_SOC_GTM601 is not set
 | |
| +# CONFIG_SND_SOC_ICS43432 is not set
 | |
| +# CONFIG_SND_SOC_IMG is not set
 | |
| +# CONFIG_SND_SOC_IMX_AUDMIX is not set
 | |
| +# CONFIG_SND_SOC_IMX_AUDMUX is not set
 | |
| +# CONFIG_SND_SOC_IMX_ES8328 is not set
 | |
| +# CONFIG_SND_SOC_IMX_SPDIF is not set
 | |
| +# CONFIG_SND_SOC_IMX_WM8962 is not set
 | |
| +# CONFIG_SND_SOC_INNO_RK3036 is not set
 | |
| +# CONFIG_SND_SOC_INTEL_APL is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BAYTRAIL is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BXT_RT298_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CATPT is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CFL is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CML_H is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CML_LP is not set
 | |
| +# CONFIG_SND_SOC_INTEL_CNL is not set
 | |
| +# CONFIG_SND_SOC_INTEL_GLK is not set
 | |
| +# CONFIG_SND_SOC_INTEL_HASWELL is not set
 | |
| +# CONFIG_SND_SOC_INTEL_KBL is not set
 | |
| +# CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_KEEMBAY is not set
 | |
| +# CONFIG_SND_SOC_INTEL_SKL is not set
 | |
| +# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_SKL_RT286_MACH is not set
 | |
| +# CONFIG_SND_SOC_INTEL_SKYLAKE is not set
 | |
| +# CONFIG_SND_SOC_INTEL_SST is not set
 | |
| +CONFIG_SND_SOC_INTEL_SST_TOPLEVEL=y
 | |
| +# CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES is not set
 | |
| +# CONFIG_SND_SOC_JZ4725B_CODEC is not set
 | |
| +# CONFIG_SND_SOC_JZ4740_CODEC is not set
 | |
| +# CONFIG_SND_SOC_JZ4770_CODEC is not set
 | |
| +# CONFIG_SND_SOC_MA120X0P is not set
 | |
| +# CONFIG_SND_SOC_MAX9759 is not set
 | |
| +# CONFIG_SND_SOC_MAX98088 is not set
 | |
| +# CONFIG_SND_SOC_MAX98357A is not set
 | |
| +# CONFIG_SND_SOC_MAX98373 is not set
 | |
| +# CONFIG_SND_SOC_MAX98373_I2C is not set
 | |
| +# CONFIG_SND_SOC_MAX98390 is not set
 | |
| +# CONFIG_SND_SOC_MAX98504 is not set
 | |
| +# CONFIG_SND_SOC_MAX9860 is not set
 | |
| +# CONFIG_SND_SOC_MAX9867 is not set
 | |
| +# CONFIG_SND_SOC_MAX98927 is not set
 | |
| +# CONFIG_SND_SOC_MEDIATEK is not set
 | |
| +# CONFIG_SND_SOC_MPC5200_AC97 is not set
 | |
| +# CONFIG_SND_SOC_MPC5200_I2S is not set
 | |
| +# CONFIG_SND_SOC_MSM8916_WCD_ANALOG is not set
 | |
| +# CONFIG_SND_SOC_MSM8916_WCD_DIGITAL is not set
 | |
| +# CONFIG_SND_SOC_MT2701 is not set
 | |
| +# CONFIG_SND_SOC_MT6351 is not set
 | |
| +# CONFIG_SND_SOC_MT6358 is not set
 | |
| +# CONFIG_SND_SOC_MT6660 is not set
 | |
| +# CONFIG_SND_SOC_MT6797 is not set
 | |
| +# CONFIG_SND_SOC_MT8173 is not set
 | |
| +# CONFIG_SND_SOC_MT8183 is not set
 | |
| +# CONFIG_SND_SOC_MTK_BTCVSD is not set
 | |
| +# CONFIG_SND_SOC_NAU8540 is not set
 | |
| +# CONFIG_SND_SOC_NAU8810 is not set
 | |
| +# CONFIG_SND_SOC_NAU8822 is not set
 | |
| +# CONFIG_SND_SOC_NAU8824 is not set
 | |
| +# CONFIG_SND_SOC_PCM1681 is not set
 | |
| +# CONFIG_SND_SOC_PCM1789_I2C is not set
 | |
| +# CONFIG_SND_SOC_PCM1792A is not set
 | |
| +# CONFIG_SND_SOC_PCM179X_I2C is not set
 | |
| +# CONFIG_SND_SOC_PCM179X_SPI is not set
 | |
| +# CONFIG_SND_SOC_PCM186X_I2C is not set
 | |
| +# CONFIG_SND_SOC_PCM186X_SPI is not set
 | |
| +# CONFIG_SND_SOC_PCM3060_I2C is not set
 | |
| +# CONFIG_SND_SOC_PCM3060_SPI is not set
 | |
| +# CONFIG_SND_SOC_PCM3168A_I2C is not set
 | |
| +# CONFIG_SND_SOC_PCM3168A_SPI is not set
 | |
| +# CONFIG_SND_SOC_PCM512x_I2C is not set
 | |
| +# CONFIG_SND_SOC_PCM512x_SPI is not set
 | |
| +# CONFIG_SND_SOC_QCOM is not set
 | |
| +# CONFIG_SND_SOC_RK3328 is not set
 | |
| +# CONFIG_SND_SOC_RT5616 is not set
 | |
| +# CONFIG_SND_SOC_RT5631 is not set
 | |
| +# CONFIG_SND_SOC_RT5677_SPI is not set
 | |
| +# CONFIG_SND_SOC_SGTL5000 is not set
 | |
| +# CONFIG_SND_SOC_SIMPLE_AMPLIFIER is not set
 | |
| +# CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set
 | |
| +# CONFIG_SND_SOC_SOF_TOPLEVEL is not set
 | |
| +# CONFIG_SND_SOC_SPDIF is not set
 | |
| +# CONFIG_SND_SOC_SSM2305 is not set
 | |
| +# CONFIG_SND_SOC_SSM2602_I2C is not set
 | |
| +# CONFIG_SND_SOC_SSM2602_SPI is not set
 | |
| +# CONFIG_SND_SOC_SSM4567 is not set
 | |
| +# CONFIG_SND_SOC_STA32X is not set
 | |
| +# CONFIG_SND_SOC_STA350 is not set
 | |
| +# CONFIG_SND_SOC_STI_SAS is not set
 | |
| +# CONFIG_SND_SOC_TAS2552 is not set
 | |
| +# CONFIG_SND_SOC_TAS2562 is not set
 | |
| +# CONFIG_SND_SOC_TAS2764 is not set
 | |
| +# CONFIG_SND_SOC_TAS2770 is not set
 | |
| +# CONFIG_SND_SOC_TAS5086 is not set
 | |
| +# CONFIG_SND_SOC_TAS571X is not set
 | |
| +# CONFIG_SND_SOC_TAS5720 is not set
 | |
| +# CONFIG_SND_SOC_TAS6424 is not set
 | |
| +# CONFIG_SND_SOC_TDA7419 is not set
 | |
| +# CONFIG_SND_SOC_TFA9879 is not set
 | |
| +# CONFIG_SND_SOC_TLV320ADCX140 is not set
 | |
| +# CONFIG_SND_SOC_TLV320AIC23_I2C is not set
 | |
| +# CONFIG_SND_SOC_TLV320AIC23_SPI is not set
 | |
| +# CONFIG_SND_SOC_TLV320AIC31XX is not set
 | |
| +# CONFIG_SND_SOC_TLV320AIC32X4_I2C is not set
 | |
| +# CONFIG_SND_SOC_TLV320AIC32X4_SPI is not set
 | |
| +# CONFIG_SND_SOC_TLV320AIC3X is not set
 | |
| +# CONFIG_SND_SOC_TPA6130A2 is not set
 | |
| +# CONFIG_SND_SOC_TS3A227E is not set
 | |
| +# CONFIG_SND_SOC_TSCS42XX is not set
 | |
| +# CONFIG_SND_SOC_TSCS454 is not set
 | |
| +# CONFIG_SND_SOC_UDA1334 is not set
 | |
| +# CONFIG_SND_SOC_WM8510 is not set
 | |
| +# CONFIG_SND_SOC_WM8523 is not set
 | |
| +# CONFIG_SND_SOC_WM8524 is not set
 | |
| +# CONFIG_SND_SOC_WM8580 is not set
 | |
| +# CONFIG_SND_SOC_WM8711 is not set
 | |
| +# CONFIG_SND_SOC_WM8728 is not set
 | |
| +# CONFIG_SND_SOC_WM8731 is not set
 | |
| +# CONFIG_SND_SOC_WM8737 is not set
 | |
| +# CONFIG_SND_SOC_WM8741 is not set
 | |
| +# CONFIG_SND_SOC_WM8750 is not set
 | |
| +# CONFIG_SND_SOC_WM8753 is not set
 | |
| +# CONFIG_SND_SOC_WM8770 is not set
 | |
| +# CONFIG_SND_SOC_WM8776 is not set
 | |
| +# CONFIG_SND_SOC_WM8782 is not set
 | |
| +# CONFIG_SND_SOC_WM8804_I2C is not set
 | |
| +# CONFIG_SND_SOC_WM8804_SPI is not set
 | |
| +# CONFIG_SND_SOC_WM8903 is not set
 | |
| +# CONFIG_SND_SOC_WM8904 is not set
 | |
| +# CONFIG_SND_SOC_WM8960 is not set
 | |
| +# CONFIG_SND_SOC_WM8962 is not set
 | |
| +# CONFIG_SND_SOC_WM8974 is not set
 | |
| +# CONFIG_SND_SOC_WM8978 is not set
 | |
| +# CONFIG_SND_SOC_WM8985 is not set
 | |
| +# CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER is not set
 | |
| +# CONFIG_SND_SOC_XILINX_I2S is not set
 | |
| +# CONFIG_SND_SOC_XILINX_SPDIF is not set
 | |
| +# CONFIG_SND_SOC_XTFPGA_I2S is not set
 | |
| +# CONFIG_SND_SOC_ZL38060 is not set
 | |
| +# CONFIG_SND_SOC_ZX_AUD96P22 is not set
 | |
| +# CONFIG_SND_SONICVIBES is not set
 | |
| +# CONFIG_SND_SPI is not set
 | |
| +# CONFIG_SND_SSCAPE is not set
 | |
| +# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI is not set
 | |
| +# CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI is not set
 | |
| +# CONFIG_SND_SUN4I_CODEC is not set
 | |
| +# CONFIG_SND_SUPPORT_OLD_API is not set
 | |
| +# CONFIG_SND_TIMER is not set
 | |
| +# CONFIG_SND_TRIDENT is not set
 | |
| +CONFIG_SND_USB=y
 | |
| +# CONFIG_SND_USB_6FIRE is not set
 | |
| +# CONFIG_SND_USB_AUDIO is not set
 | |
| +# CONFIG_SND_USB_CAIAQ is not set
 | |
| +# CONFIG_SND_USB_HIFACE is not set
 | |
| +# CONFIG_SND_USB_POD is not set
 | |
| +# CONFIG_SND_USB_PODHD is not set
 | |
| +# CONFIG_SND_USB_TONEPORT is not set
 | |
| +# CONFIG_SND_USB_UA101 is not set
 | |
| +# CONFIG_SND_USB_US122L is not set
 | |
| +# CONFIG_SND_USB_USX2Y is not set
 | |
| +# CONFIG_SND_USB_VARIAX is not set
 | |
| +# CONFIG_SND_VERBOSE_PRINTK is not set
 | |
| +CONFIG_SND_VERBOSE_PROCFS=y
 | |
| +# CONFIG_SND_VIA82XX is not set
 | |
| +# CONFIG_SND_VIA82XX_MODEM is not set
 | |
| +# CONFIG_SND_VIRTUOSO is not set
 | |
| +# CONFIG_SND_VX222 is not set
 | |
| +# CONFIG_SND_VXPOCKET is not set
 | |
| +# CONFIG_SND_WAVEFRONT is not set
 | |
| +CONFIG_SND_X86=y
 | |
| +# CONFIG_SND_XEN_FRONTEND is not set
 | |
| +# CONFIG_SND_YMFPCI is not set
 | |
| +# CONFIG_SNI_RM is not set
 | |
| +# CONFIG_SOCIONEXT_SYNQUACER_PREITS is not set
 | |
| +# CONFIG_SOCK_CGROUP_DATA is not set
 | |
| +# CONFIG_SOC_AM33XX is not set
 | |
| +# CONFIG_SOC_AM43XX is not set
 | |
| +# CONFIG_SOC_BRCMSTB is not set
 | |
| +# CONFIG_SOC_CAMERA is not set
 | |
| +# CONFIG_SOC_DRA7XX is not set
 | |
| +# CONFIG_SOC_HAS_OMAP2_SDRC is not set
 | |
| +# CONFIG_SOC_OMAP5 is not set
 | |
| +# CONFIG_SOC_TI is not set
 | |
| +# CONFIG_SOFTLOCKUP_DETECTOR is not set
 | |
| +# CONFIG_SOFT_WATCHDOG is not set
 | |
| +# CONFIG_SOLARIS_X86_PARTITION is not set
 | |
| +# CONFIG_SONYPI is not set
 | |
| +# CONFIG_SONY_LAPTOP is not set
 | |
| +# CONFIG_SOUND is not set
 | |
| +# CONFIG_SOUNDWIRE is not set
 | |
| +# CONFIG_SOUND_OSS_CORE is not set
 | |
| +# CONFIG_SOUND_OSS_CORE_PRECLAIM is not set
 | |
| +# CONFIG_SOUND_PRIME is not set
 | |
| +# CONFIG_SP5100_TCO is not set
 | |
| +# CONFIG_SPARSEMEM_MANUAL is not set
 | |
| +# CONFIG_SPARSEMEM_STATIC is not set
 | |
| +# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 | |
| +# CONFIG_SPARSE_IRQ is not set
 | |
| +# CONFIG_SPARSE_RCU_POINTER is not set
 | |
| +# CONFIG_SPEAKUP is not set
 | |
| +# CONFIG_SPI is not set
 | |
| +# CONFIG_SPINLOCK_TEST is not set
 | |
| +# CONFIG_SPI_ALTERA is not set
 | |
| +# CONFIG_SPI_AMD is not set
 | |
| +# CONFIG_SPI_AU1550 is not set
 | |
| +# CONFIG_SPI_AXI_SPI_ENGINE is not set
 | |
| +# CONFIG_SPI_BCM2835 is not set
 | |
| +# CONFIG_SPI_BCM_QSPI is not set
 | |
| +# CONFIG_SPI_BITBANG is not set
 | |
| +# CONFIG_SPI_BUTTERFLY is not set
 | |
| +# CONFIG_SPI_CADENCE is not set
 | |
| +# CONFIG_SPI_CADENCE_QUADSPI is not set
 | |
| +# CONFIG_SPI_DEBUG is not set
 | |
| +# CONFIG_SPI_DESIGNWARE is not set
 | |
| +# CONFIG_SPI_FSL_DSPI is not set
 | |
| +# CONFIG_SPI_FSL_ESPI is not set
 | |
| +# CONFIG_SPI_FSL_SPI is not set
 | |
| +# CONFIG_SPI_GPIO is not set
 | |
| +# CONFIG_SPI_GPIO_OLD is not set
 | |
| +# CONFIG_SPI_IMG_SPFI is not set
 | |
| +# CONFIG_SPI_LANTIQ_SSC is not set
 | |
| +# CONFIG_SPI_LM70_LLP is not set
 | |
| +# CONFIG_SPI_LOOPBACK_TEST is not set
 | |
| +# CONFIG_SPI_MASTER is not set
 | |
| +# CONFIG_SPI_MEM is not set
 | |
| +# CONFIG_SPI_MPC52xx is not set
 | |
| +# CONFIG_SPI_MPC52xx_PSC is not set
 | |
| +# CONFIG_SPI_MTK_QUADSPI is not set
 | |
| +# CONFIG_SPI_MUX is not set
 | |
| +# CONFIG_SPI_MXIC is not set
 | |
| +# CONFIG_SPI_NXP_FLEXSPI is not set
 | |
| +# CONFIG_SPI_OCTEON is not set
 | |
| +# CONFIG_SPI_OC_TINY is not set
 | |
| +# CONFIG_SPI_ORION is not set
 | |
| +# CONFIG_SPI_PL022 is not set
 | |
| +# CONFIG_SPI_PPC4xx is not set
 | |
| +# CONFIG_SPI_PXA2XX is not set
 | |
| +# CONFIG_SPI_PXA2XX_PCI is not set
 | |
| +# CONFIG_SPI_QCOM_QSPI is not set
 | |
| +# CONFIG_SPI_ROCKCHIP is not set
 | |
| +# CONFIG_SPI_S3C64XX is not set
 | |
| +# CONFIG_SPI_SC18IS602 is not set
 | |
| +# CONFIG_SPI_SIFIVE is not set
 | |
| +# CONFIG_SPI_SLAVE is not set
 | |
| +# CONFIG_SPI_SPIDEV is not set
 | |
| +# CONFIG_SPI_THUNDERX is not set
 | |
| +# CONFIG_SPI_TI_QSPI is not set
 | |
| +# CONFIG_SPI_TLE62X0 is not set
 | |
| +# CONFIG_SPI_TOPCLIFF_PCH is not set
 | |
| +# CONFIG_SPI_XCOMM is not set
 | |
| +# CONFIG_SPI_XILINX is not set
 | |
| +# CONFIG_SPI_XWAY is not set
 | |
| +# CONFIG_SPI_ZYNQMP_GQSPI is not set
 | |
| +CONFIG_SPLIT_PTLOCK_CPUS=4
 | |
| +# CONFIG_SPMI is not set
 | |
| +# CONFIG_SPS30 is not set
 | |
| +CONFIG_SQUASHFS=y
 | |
| +# CONFIG_SQUASHFS_4K_DEVBLK_SIZE is not set
 | |
| +# CONFIG_SQUASHFS_DECOMP_MULTI is not set
 | |
| +CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU=y
 | |
| +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set
 | |
| +CONFIG_SQUASHFS_EMBEDDED=y
 | |
| +# CONFIG_SQUASHFS_FILE_CACHE is not set
 | |
| +CONFIG_SQUASHFS_FILE_DIRECT=y
 | |
| +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
 | |
| +# CONFIG_SQUASHFS_LZ4 is not set
 | |
| +# CONFIG_SQUASHFS_LZO is not set
 | |
| +# CONFIG_SQUASHFS_XATTR is not set
 | |
| +CONFIG_SQUASHFS_XZ=y
 | |
| +# CONFIG_SQUASHFS_ZLIB is not set
 | |
| +# CONFIG_SQUASHFS_ZSTD is not set
 | |
| +# CONFIG_SRAM is not set
 | |
| +# CONFIG_SRF04 is not set
 | |
| +# CONFIG_SRF08 is not set
 | |
| +# CONFIG_SSB is not set
 | |
| +# CONFIG_SSB_DEBUG is not set
 | |
| +# CONFIG_SSB_DRIVER_GPIO is not set
 | |
| +# CONFIG_SSB_HOST_SOC is not set
 | |
| +# CONFIG_SSB_PCMCIAHOST is not set
 | |
| +CONFIG_SSB_POSSIBLE=y
 | |
| +# CONFIG_SSB_SDIOHOST is not set
 | |
| +# CONFIG_SSB_SILENT is not set
 | |
| +# CONFIG_SSFDC is not set
 | |
| +# CONFIG_STACKPROTECTOR is not set
 | |
| +# CONFIG_STACKPROTECTOR_STRONG is not set
 | |
| +# CONFIG_STACKTRACE is not set
 | |
| +CONFIG_STACKTRACE_SUPPORT=y
 | |
| +# CONFIG_STACK_TRACER is not set
 | |
| +# CONFIG_STACK_VALIDATION is not set
 | |
| +CONFIG_STAGING=y
 | |
| +# CONFIG_STAGING_BOARD is not set
 | |
| +# CONFIG_STAGING_GASKET_FRAMEWORK is not set
 | |
| +# CONFIG_STAGING_MEDIA is not set
 | |
| +CONFIG_STANDALONE=y
 | |
| +# CONFIG_STATIC_KEYS_SELFTEST is not set
 | |
| +# CONFIG_STATIC_USERMODEHELPER is not set
 | |
| +CONFIG_STDBINUTILS=y
 | |
| +# CONFIG_STE10XP is not set
 | |
| +# CONFIG_STE_MODEM_RPROC is not set
 | |
| +# CONFIG_STK3310 is not set
 | |
| +# CONFIG_STK8312 is not set
 | |
| +# CONFIG_STK8BA50 is not set
 | |
| +# CONFIG_STM is not set
 | |
| +# CONFIG_STMMAC_ETH is not set
 | |
| +# CONFIG_STMMAC_PCI is not set
 | |
| +# CONFIG_STMMAC_PLATFORM is not set
 | |
| +# CONFIG_STM_DUMMY is not set
 | |
| +# CONFIG_STM_SOURCE_CONSOLE is not set
 | |
| +CONFIG_STP=y
 | |
| +# CONFIG_STREAM_PARSER is not set
 | |
| +# CONFIG_STRICT_DEVMEM is not set
 | |
| +CONFIG_STRICT_KERNEL_RWX=y
 | |
| +CONFIG_STRICT_MODULE_RWX=y
 | |
| +# CONFIG_STRING_SELFTEST is not set
 | |
| +CONFIG_STRIP_ASM_SYMS=y
 | |
| +# CONFIG_STX104 is not set
 | |
| +# CONFIG_ST_UVIS25 is not set
 | |
| +# CONFIG_SUN4I_GPADC is not set
 | |
| +# CONFIG_SUN50I_DE2_BUS is not set
 | |
| +# CONFIG_SUN50I_ERRATUM_UNKNOWN1 is not set
 | |
| +# CONFIG_SUNDANCE is not set
 | |
| +# CONFIG_SUNGEM is not set
 | |
| +# CONFIG_SUNRPC is not set
 | |
| +# CONFIG_SUNRPC_DEBUG is not set
 | |
| +CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y
 | |
| +# CONFIG_SUNRPC_GSS is not set
 | |
| +# CONFIG_SUNXI_SRAM is not set
 | |
| +# CONFIG_SUN_PARTITION is not set
 | |
| +# CONFIG_SURFACE_3_BUTTON is not set
 | |
| +# CONFIG_SUSPEND is not set
 | |
| +# CONFIG_SUSPEND_SKIP_SYNC is not set
 | |
| +CONFIG_SWAP=y
 | |
| +# CONFIG_SWCONFIG is not set
 | |
| +# CONFIG_SWCONFIG_B53 is not set
 | |
| +# CONFIG_SWCONFIG_B53_MDIO_DRIVER is not set
 | |
| +# CONFIG_SWCONFIG_B53_MMAP_DRIVER is not set
 | |
| +# CONFIG_SWCONFIG_B53_SPI_DRIVER is not set
 | |
| +# CONFIG_SWCONFIG_B53_SRAB_DRIVER is not set
 | |
| +# CONFIG_SWCONFIG_LEDS is not set
 | |
| +# CONFIG_SW_SYNC is not set
 | |
| +# CONFIG_SX9310 is not set
 | |
| +# CONFIG_SX9500 is not set
 | |
| +# CONFIG_SXGBE_ETH is not set
 | |
| +CONFIG_SYMBOLIC_ERRNAME=y
 | |
| +# CONFIG_SYNCLINK_CS is not set
 | |
| +# CONFIG_SYNC_FILE is not set
 | |
| +# CONFIG_SYNOPSYS_DWC_ETH_QOS is not set
 | |
| +# CONFIG_SYNTH_EVENTS is not set
 | |
| +CONFIG_SYN_COOKIES=y
 | |
| +# CONFIG_SYSCON_REBOOT_MODE is not set
 | |
| +CONFIG_SYSCTL=y
 | |
| +# CONFIG_SYSCTL_SYSCALL is not set
 | |
| +CONFIG_SYSFS=y
 | |
| +# CONFIG_SYSFS_DEPRECATED is not set
 | |
| +# CONFIG_SYSFS_DEPRECATED_V2 is not set
 | |
| +# CONFIG_SYSFS_SYSCALL is not set
 | |
| +# CONFIG_SYSTEMPORT is not set
 | |
| +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
 | |
| +# CONFIG_SYSTEM_DATA_VERIFICATION is not set
 | |
| +# CONFIG_SYSTEM_TRUSTED_KEYRING is not set
 | |
| +CONFIG_SYSTEM_TRUSTED_KEYS=""
 | |
| +# CONFIG_SYSV68_PARTITION is not set
 | |
| +CONFIG_SYSVIPC=y
 | |
| +CONFIG_SYSVIPC_SYSCTL=y
 | |
| +# CONFIG_SYSV_FS is not set
 | |
| +# CONFIG_SYS_HYPERVISOR is not set
 | |
| +# CONFIG_T5403 is not set
 | |
| +# CONFIG_TARGET_CORE is not set
 | |
| +# CONFIG_TASKSTATS is not set
 | |
| +# CONFIG_TASKS_RCU is not set
 | |
| +CONFIG_TASKS_TRACE_RCU_READ_MB=y
 | |
| +# CONFIG_TASK_XACCT is not set
 | |
| +# CONFIG_TC35815 is not set
 | |
| +# CONFIG_TCG_ATMEL is not set
 | |
| +# CONFIG_TCG_CRB is not set
 | |
| +# CONFIG_TCG_FTPM_TEE is not set
 | |
| +# CONFIG_TCG_INFINEON is not set
 | |
| +# CONFIG_TCG_NSC is not set
 | |
| +# CONFIG_TCG_ST33_I2C is not set
 | |
| +# CONFIG_TCG_TIS is not set
 | |
| +# CONFIG_TCG_TIS_I2C_ATMEL is not set
 | |
| +# CONFIG_TCG_TIS_I2C_INFINEON is not set
 | |
| +# CONFIG_TCG_TIS_I2C_NUVOTON is not set
 | |
| +# CONFIG_TCG_TIS_SPI is not set
 | |
| +# CONFIG_TCG_TIS_ST33ZP24_I2C is not set
 | |
| +# CONFIG_TCG_TIS_ST33ZP24_SPI is not set
 | |
| +# CONFIG_TCG_TPM is not set
 | |
| +# CONFIG_TCG_VTPM_PROXY is not set
 | |
| +# CONFIG_TCG_XEN is not set
 | |
| +# CONFIG_TCIC is not set
 | |
| +CONFIG_TCP_CONG_ADVANCED=y
 | |
| +# CONFIG_TCP_CONG_BBR is not set
 | |
| +# CONFIG_TCP_CONG_BIC is not set
 | |
| +# CONFIG_TCP_CONG_CDG is not set
 | |
| +CONFIG_TCP_CONG_CUBIC=y
 | |
| +# CONFIG_TCP_CONG_DCTCP is not set
 | |
| +# CONFIG_TCP_CONG_HSTCP is not set
 | |
| +# CONFIG_TCP_CONG_HTCP is not set
 | |
| +# CONFIG_TCP_CONG_HYBLA is not set
 | |
| +# CONFIG_TCP_CONG_ILLINOIS is not set
 | |
| +# CONFIG_TCP_CONG_LP is not set
 | |
| +# CONFIG_TCP_CONG_NV is not set
 | |
| +# CONFIG_TCP_CONG_SCALABLE is not set
 | |
| +# CONFIG_TCP_CONG_VEGAS is not set
 | |
| +# CONFIG_TCP_CONG_VENO is not set
 | |
| +# CONFIG_TCP_CONG_WESTWOOD is not set
 | |
| +# CONFIG_TCP_CONG_YEAH is not set
 | |
| +# CONFIG_TCP_MD5SIG is not set
 | |
| +# CONFIG_TCS3414 is not set
 | |
| +# CONFIG_TCS3472 is not set
 | |
| +# CONFIG_TEE is not set
 | |
| +# CONFIG_TEGRA_AHB is not set
 | |
| +# CONFIG_TEGRA_HOST1X is not set
 | |
| +# CONFIG_TEHUTI is not set
 | |
| +# CONFIG_TERANETICS_PHY is not set
 | |
| +# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
 | |
| +# CONFIG_TEST_BITFIELD is not set
 | |
| +# CONFIG_TEST_BITMAP is not set
 | |
| +# CONFIG_TEST_BITOPS is not set
 | |
| +# CONFIG_TEST_BLACKHOLE_DEV is not set
 | |
| +# CONFIG_TEST_BPF is not set
 | |
| +# CONFIG_TEST_FIRMWARE is not set
 | |
| +# CONFIG_TEST_FREE_PAGES is not set
 | |
| +# CONFIG_TEST_HASH is not set
 | |
| +# CONFIG_TEST_HEXDUMP is not set
 | |
| +# CONFIG_TEST_IDA is not set
 | |
| +# CONFIG_TEST_KMOD is not set
 | |
| +# CONFIG_TEST_KSTRTOX is not set
 | |
| +# CONFIG_TEST_LIST_SORT is not set
 | |
| +# CONFIG_TEST_LKM is not set
 | |
| +# CONFIG_TEST_LOCKUP is not set
 | |
| +# CONFIG_TEST_MEMCAT_P is not set
 | |
| +# CONFIG_TEST_MEMINIT is not set
 | |
| +# CONFIG_TEST_MIN_HEAP is not set
 | |
| +# CONFIG_TEST_OVERFLOW is not set
 | |
| +# CONFIG_TEST_POWER is not set
 | |
| +# CONFIG_TEST_PRINTF is not set
 | |
| +# CONFIG_TEST_RHASHTABLE is not set
 | |
| +# CONFIG_TEST_SORT is not set
 | |
| +# CONFIG_TEST_STACKINIT is not set
 | |
| +# CONFIG_TEST_STATIC_KEYS is not set
 | |
| +# CONFIG_TEST_STRING_HELPERS is not set
 | |
| +# CONFIG_TEST_STRSCPY is not set
 | |
| +# CONFIG_TEST_SYSCTL is not set
 | |
| +# CONFIG_TEST_UDELAY is not set
 | |
| +# CONFIG_TEST_USER_COPY is not set
 | |
| +# CONFIG_TEST_UUID is not set
 | |
| +# CONFIG_TEST_VMALLOC is not set
 | |
| +# CONFIG_TEST_XARRAY is not set
 | |
| +CONFIG_TEXTSEARCH=y
 | |
| +# CONFIG_TEXTSEARCH_BM is not set
 | |
| +# CONFIG_TEXTSEARCH_FSM is not set
 | |
| +# CONFIG_TEXTSEARCH_KMP is not set
 | |
| +# CONFIG_THERMAL is not set
 | |
| +# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
 | |
| +# CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set
 | |
| +# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
 | |
| +# CONFIG_THERMAL_EMULATION is not set
 | |
| +# CONFIG_THERMAL_GOV_BANG_BANG is not set
 | |
| +# CONFIG_THERMAL_GOV_FAIR_SHARE is not set
 | |
| +# CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set
 | |
| +# CONFIG_THERMAL_GOV_USER_SPACE is not set
 | |
| +# CONFIG_THERMAL_HWMON is not set
 | |
| +# CONFIG_THERMAL_MMIO is not set
 | |
| +# CONFIG_THERMAL_NETLINK is not set
 | |
| +# CONFIG_THERMAL_STATISTICS is not set
 | |
| +# CONFIG_THERMAL_WRITABLE_TRIPS is not set
 | |
| +# CONFIG_THINKPAD_ACPI is not set
 | |
| +CONFIG_THIN_ARCHIVES=y
 | |
| +# CONFIG_THRUSTMASTER_FF is not set
 | |
| +# CONFIG_THUMB2_KERNEL is not set
 | |
| +# CONFIG_THUNDERBOLT is not set
 | |
| +# CONFIG_THUNDER_NIC_BGX is not set
 | |
| +# CONFIG_THUNDER_NIC_PF is not set
 | |
| +# CONFIG_THUNDER_NIC_RGX is not set
 | |
| +# CONFIG_THUNDER_NIC_VF is not set
 | |
| +# CONFIG_TICK_CPU_ACCOUNTING is not set
 | |
| +CONFIG_TICK_ONESHOT=y
 | |
| +# CONFIG_TIFM_CORE is not set
 | |
| +# CONFIG_TIGON3 is not set
 | |
| +# CONFIG_TIMB_DMA is not set
 | |
| +CONFIG_TIMERFD=y
 | |
| +# CONFIG_TIMER_STATS is not set
 | |
| +# CONFIG_TIME_NS is not set
 | |
| +# CONFIG_TINYDRM_HX8357D is not set
 | |
| +# CONFIG_TINYDRM_ILI9225 is not set
 | |
| +# CONFIG_TINYDRM_ILI9341 is not set
 | |
| +# CONFIG_TINYDRM_ILI9486 is not set
 | |
| +# CONFIG_TINYDRM_MI0283QT is not set
 | |
| +# CONFIG_TINYDRM_REPAPER is not set
 | |
| +# CONFIG_TINYDRM_ST7586 is not set
 | |
| +# CONFIG_TINYDRM_ST7735R is not set
 | |
| +CONFIG_TINY_RCU=y
 | |
| +# CONFIG_TIPC is not set
 | |
| +# CONFIG_TI_ADC081C is not set
 | |
| +# CONFIG_TI_ADC0832 is not set
 | |
| +# CONFIG_TI_ADC084S021 is not set
 | |
| +# CONFIG_TI_ADC108S102 is not set
 | |
| +# CONFIG_TI_ADC12138 is not set
 | |
| +# CONFIG_TI_ADC128S052 is not set
 | |
| +# CONFIG_TI_ADC161S626 is not set
 | |
| +# CONFIG_TI_ADS1015 is not set
 | |
| +# CONFIG_TI_ADS124S08 is not set
 | |
| +# CONFIG_TI_ADS7950 is not set
 | |
| +# CONFIG_TI_ADS8344 is not set
 | |
| +# CONFIG_TI_ADS8688 is not set
 | |
| +# CONFIG_TI_AM335X_ADC is not set
 | |
| +# CONFIG_TI_CPSW is not set
 | |
| +# CONFIG_TI_CPSW_ALE is not set
 | |
| +# CONFIG_TI_CPSW_PHY_SEL is not set
 | |
| +# CONFIG_TI_CPTS is not set
 | |
| +# CONFIG_TI_DAC082S085 is not set
 | |
| +# CONFIG_TI_DAC5571 is not set
 | |
| +# CONFIG_TI_DAC7311 is not set
 | |
| +# CONFIG_TI_DAC7512 is not set
 | |
| +# CONFIG_TI_DAC7612 is not set
 | |
| +# CONFIG_TI_DAVINCI_CPDMA is not set
 | |
| +# CONFIG_TI_DAVINCI_MDIO is not set
 | |
| +# CONFIG_TI_ST is not set
 | |
| +# CONFIG_TI_SYSCON_RESET is not set
 | |
| +# CONFIG_TI_TLC4541 is not set
 | |
| +# CONFIG_TLAN is not set
 | |
| +# CONFIG_TLS is not set
 | |
| +# CONFIG_TMD_HERMES is not set
 | |
| +# CONFIG_TMP006 is not set
 | |
| +# CONFIG_TMP007 is not set
 | |
| +CONFIG_TMPFS=y
 | |
| +# CONFIG_TMPFS_INODE64 is not set
 | |
| +# CONFIG_TMPFS_POSIX_ACL is not set
 | |
| +CONFIG_TMPFS_XATTR=y
 | |
| +# CONFIG_TOPSTAR_LAPTOP is not set
 | |
| +# CONFIG_TORTURE_TEST is not set
 | |
| +# CONFIG_TOSHIBA_HAPS is not set
 | |
| +# CONFIG_TOUCHSCREEN_88PM860X is not set
 | |
| +# CONFIG_TOUCHSCREEN_AD7877 is not set
 | |
| +# CONFIG_TOUCHSCREEN_AD7879 is not set
 | |
| +# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
 | |
| +# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
 | |
| +# CONFIG_TOUCHSCREEN_ADC is not set
 | |
| +# CONFIG_TOUCHSCREEN_ADS7846 is not set
 | |
| +# CONFIG_TOUCHSCREEN_AR1021_I2C is not set
 | |
| +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
 | |
| +# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set
 | |
| +# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
 | |
| +# CONFIG_TOUCHSCREEN_BU21013 is not set
 | |
| +# CONFIG_TOUCHSCREEN_BU21029 is not set
 | |
| +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set
 | |
| +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set
 | |
| +# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set
 | |
| +# CONFIG_TOUCHSCREEN_CY8CTMA140 is not set
 | |
| +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
 | |
| +# CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set
 | |
| +# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set
 | |
| +# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set
 | |
| +# CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set
 | |
| +# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set
 | |
| +# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set
 | |
| +# CONFIG_TOUCHSCREEN_DA9034 is not set
 | |
| +# CONFIG_TOUCHSCREEN_DA9052 is not set
 | |
| +# CONFIG_TOUCHSCREEN_DYNAPRO is not set
 | |
| +# CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set
 | |
| +# CONFIG_TOUCHSCREEN_EETI is not set
 | |
| +# CONFIG_TOUCHSCREEN_EGALAX is not set
 | |
| +# CONFIG_TOUCHSCREEN_EGALAX_SERIAL is not set
 | |
| +# CONFIG_TOUCHSCREEN_EKTF2127 is not set
 | |
| +# CONFIG_TOUCHSCREEN_ELAN is not set
 | |
| +# CONFIG_TOUCHSCREEN_ELO is not set
 | |
| +# CONFIG_TOUCHSCREEN_EXC3000 is not set
 | |
| +# CONFIG_TOUCHSCREEN_FUJITSU is not set
 | |
| +# CONFIG_TOUCHSCREEN_GOODIX is not set
 | |
| +# CONFIG_TOUCHSCREEN_GUNZE is not set
 | |
| +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
 | |
| +# CONFIG_TOUCHSCREEN_HIDEEP is not set
 | |
| +# CONFIG_TOUCHSCREEN_HP600 is not set
 | |
| +# CONFIG_TOUCHSCREEN_HP7XX is not set
 | |
| +# CONFIG_TOUCHSCREEN_HTCPEN is not set
 | |
| +# CONFIG_TOUCHSCREEN_ILI210X is not set
 | |
| +# CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set
 | |
| +# CONFIG_TOUCHSCREEN_INEXIO is not set
 | |
| +# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set
 | |
| +# CONFIG_TOUCHSCREEN_IPROC is not set
 | |
| +# CONFIG_TOUCHSCREEN_IQS5XX is not set
 | |
| +# CONFIG_TOUCHSCREEN_LPC32XX is not set
 | |
| +# CONFIG_TOUCHSCREEN_MAX11801 is not set
 | |
| +# CONFIG_TOUCHSCREEN_MC13783 is not set
 | |
| +# CONFIG_TOUCHSCREEN_MCS5000 is not set
 | |
| +# CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set
 | |
| +# CONFIG_TOUCHSCREEN_MIGOR is not set
 | |
| +# CONFIG_TOUCHSCREEN_MK712 is not set
 | |
| +# CONFIG_TOUCHSCREEN_MMS114 is not set
 | |
| +# CONFIG_TOUCHSCREEN_MTOUCH is not set
 | |
| +# CONFIG_TOUCHSCREEN_MX25 is not set
 | |
| +# CONFIG_TOUCHSCREEN_MXS_LRADC is not set
 | |
| +# CONFIG_TOUCHSCREEN_PCAP is not set
 | |
| +# CONFIG_TOUCHSCREEN_PENMOUNT is not set
 | |
| +# CONFIG_TOUCHSCREEN_PIXCIR is not set
 | |
| +# CONFIG_TOUCHSCREEN_PROPERTIES is not set
 | |
| +# CONFIG_TOUCHSCREEN_RASPBERRYPI_FW is not set
 | |
| +# CONFIG_TOUCHSCREEN_RM_TS is not set
 | |
| +# CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set
 | |
| +# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set
 | |
| +# CONFIG_TOUCHSCREEN_S3C2410 is not set
 | |
| +# CONFIG_TOUCHSCREEN_S6SY761 is not set
 | |
| +# CONFIG_TOUCHSCREEN_SILEAD is not set
 | |
| +# CONFIG_TOUCHSCREEN_SIS_I2C is not set
 | |
| +# CONFIG_TOUCHSCREEN_ST1232 is not set
 | |
| +# CONFIG_TOUCHSCREEN_STMFTS is not set
 | |
| +# CONFIG_TOUCHSCREEN_STMPE is not set
 | |
| +# CONFIG_TOUCHSCREEN_SUN4I is not set
 | |
| +# CONFIG_TOUCHSCREEN_SUR40 is not set
 | |
| +# CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set
 | |
| +# CONFIG_TOUCHSCREEN_SX8654 is not set
 | |
| +# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set
 | |
| +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
 | |
| +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
 | |
| +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
 | |
| +# CONFIG_TOUCHSCREEN_TPS6507X is not set
 | |
| +# CONFIG_TOUCHSCREEN_TS4800 is not set
 | |
| +# CONFIG_TOUCHSCREEN_TSC2004 is not set
 | |
| +# CONFIG_TOUCHSCREEN_TSC2005 is not set
 | |
| +# CONFIG_TOUCHSCREEN_TSC2007 is not set
 | |
| +# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set
 | |
| +# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set
 | |
| +# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
 | |
| +# CONFIG_TOUCHSCREEN_UCB1400 is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_3M is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_E2I is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_EGALAX is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_ELO is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_ETURBO is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_GOTOP is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_GUNZE is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_ITM is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_JASTEC is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_NEXIO is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_PANJIT is not set
 | |
| +# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set
 | |
| +# CONFIG_TOUCHSCREEN_W90X900 is not set
 | |
| +# CONFIG_TOUCHSCREEN_WACOM_I2C is not set
 | |
| +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
 | |
| +# CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set
 | |
| +# CONFIG_TOUCHSCREEN_WM831X is not set
 | |
| +# CONFIG_TOUCHSCREEN_WM9705 is not set
 | |
| +# CONFIG_TOUCHSCREEN_WM9712 is not set
 | |
| +# CONFIG_TOUCHSCREEN_WM9713 is not set
 | |
| +# CONFIG_TOUCHSCREEN_WM97XX is not set
 | |
| +# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set
 | |
| +# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set
 | |
| +# CONFIG_TOUCHSCREEN_ZET6223 is not set
 | |
| +# CONFIG_TOUCHSCREEN_ZFORCE is not set
 | |
| +# CONFIG_TOUCHSCREEN_ZINITIX is not set
 | |
| +# CONFIG_TPL0102 is not set
 | |
| +# CONFIG_TPS6105X is not set
 | |
| +# CONFIG_TPS65010 is not set
 | |
| +# CONFIG_TPS6507X is not set
 | |
| +# CONFIG_TRACEPOINT_BENCHMARK is not set
 | |
| +# CONFIG_TRACER_SNAPSHOT is not set
 | |
| +# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
 | |
| +# CONFIG_TRACE_BRANCH_PROFILING is not set
 | |
| +# CONFIG_TRACE_EVAL_MAP_FILE is not set
 | |
| +# CONFIG_TRACE_EVENT_INJECT is not set
 | |
| +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
 | |
| +# CONFIG_TRACE_SINK is not set
 | |
| +# CONFIG_TRACING_EVENTS_GPIO is not set
 | |
| +CONFIG_TRACING_SUPPORT=y
 | |
| +CONFIG_TRAD_SIGNALS=y
 | |
| +# CONFIG_TRANSPARENT_HUGEPAGE is not set
 | |
| +# CONFIG_TREE_RCU is not set
 | |
| +# CONFIG_TREE_RCU_TRACE is not set
 | |
| +# CONFIG_TRIM_UNUSED_KSYMS is not set
 | |
| +# CONFIG_TRUSTED_FOUNDATIONS is not set
 | |
| +# CONFIG_TRUSTED_KEYS is not set
 | |
| +# CONFIG_TSL2583 is not set
 | |
| +# CONFIG_TSL2772 is not set
 | |
| +# CONFIG_TSL2x7x is not set
 | |
| +# CONFIG_TSL4531 is not set
 | |
| +# CONFIG_TSYS01 is not set
 | |
| +# CONFIG_TSYS02D is not set
 | |
| +# CONFIG_TTPCI_EEPROM is not set
 | |
| +CONFIG_TTY=y
 | |
| +# CONFIG_TTY_PRINTK is not set
 | |
| +# CONFIG_TUN is not set
 | |
| +# CONFIG_TUN_VNET_CROSS_LE is not set
 | |
| +# CONFIG_TWL4030_CORE is not set
 | |
| +# CONFIG_TWL4030_MADC is not set
 | |
| +# CONFIG_TWL6030_GPADC is not set
 | |
| +# CONFIG_TWL6040_CORE is not set
 | |
| +# CONFIG_TYPEC is not set
 | |
| +# CONFIG_TYPEC_TCPM is not set
 | |
| +# CONFIG_TYPEC_UCSI is not set
 | |
| +# CONFIG_TYPHOON is not set
 | |
| +# CONFIG_UACCESS_WITH_MEMCPY is not set
 | |
| +# CONFIG_UBIFS_ATIME_SUPPORT is not set
 | |
| +# CONFIG_UBIFS_FS_AUTHENTICATION is not set
 | |
| +# CONFIG_UBIFS_FS_ENCRYPTION is not set
 | |
| +# CONFIG_UBIFS_FS_SECURITY is not set
 | |
| +CONFIG_UBIFS_FS_XATTR=y
 | |
| +# CONFIG_UBIFS_FS_ZLIB is not set
 | |
| +# CONFIG_UBIFS_FS_ZSTD is not set
 | |
| +# CONFIG_UBSAN is not set
 | |
| +CONFIG_UBSAN_ALIGNMENT=y
 | |
| +# CONFIG_UCB1400_CORE is not set
 | |
| +# CONFIG_UCSI is not set
 | |
| +# CONFIG_UDF_FS is not set
 | |
| +# CONFIG_UDMABUF is not set
 | |
| +CONFIG_UEVENT_HELPER=y
 | |
| +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 | |
| +# CONFIG_UFS_FS is not set
 | |
| +# CONFIG_UHID is not set
 | |
| +CONFIG_UID16=y
 | |
| +# CONFIG_UIO is not set
 | |
| +# CONFIG_ULTRA is not set
 | |
| +# CONFIG_ULTRIX_PARTITION is not set
 | |
| +# CONFIG_UNICODE is not set
 | |
| +# CONFIG_UNISYSSPAR is not set
 | |
| +# CONFIG_UNISYS_VISORBUS is not set
 | |
| +CONFIG_UNIX=y
 | |
| +CONFIG_UNIX98_PTYS=y
 | |
| +# CONFIG_UNIXWARE_DISKLABEL is not set
 | |
| +# CONFIG_UNIX_DIAG is not set
 | |
| +CONFIG_UNIX_SCM=y
 | |
| +# CONFIG_UNUSED_SYMBOLS is not set
 | |
| +# CONFIG_UNWINDER_FRAME_POINTER is not set
 | |
| +# CONFIG_UPROBES is not set
 | |
| +# CONFIG_UPROBE_EVENTS is not set
 | |
| +# CONFIG_US5182D is not set
 | |
| +# CONFIG_USB is not set
 | |
| +# CONFIG_USB4 is not set
 | |
| +# CONFIG_USBIP_CORE is not set
 | |
| +CONFIG_USBIP_VHCI_HC_PORTS=8
 | |
| +CONFIG_USBIP_VHCI_NR_HCS=1
 | |
| +# CONFIG_USBIP_VUDC is not set
 | |
| +# CONFIG_USBPCWATCHDOG is not set
 | |
| +# CONFIG_USB_ACM is not set
 | |
| +# CONFIG_USB_ADUTUX is not set
 | |
| +# CONFIG_USB_AIRSPY is not set
 | |
| +CONFIG_USB_ALI_M5632=y
 | |
| +# CONFIG_USB_AMD5536UDC is not set
 | |
| +CONFIG_USB_AN2720=y
 | |
| +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 | |
| +# CONFIG_USB_APPLEDISPLAY is not set
 | |
| +CONFIG_USB_ARCH_HAS_HCD=y
 | |
| +CONFIG_USB_ARMLINUX=y
 | |
| +# CONFIG_USB_ATM is not set
 | |
| +CONFIG_USB_AUTOSUSPEND_DELAY=2
 | |
| +# CONFIG_USB_BDC_UDC is not set
 | |
| +CONFIG_USB_BELKIN=y
 | |
| +# CONFIG_USB_C67X00_HCD is not set
 | |
| +# CONFIG_USB_CATC is not set
 | |
| +# CONFIG_USB_CDC_COMPOSITE is not set
 | |
| +# CONFIG_USB_CDNS3 is not set
 | |
| +# CONFIG_USB_CHAOSKEY is not set
 | |
| +# CONFIG_USB_CHIPIDEA is not set
 | |
| +# CONFIG_USB_CHIPIDEA_GENERIC is not set
 | |
| +# CONFIG_USB_CHIPIDEA_IMX is not set
 | |
| +# CONFIG_USB_CHIPIDEA_MSM is not set
 | |
| +# CONFIG_USB_CHIPIDEA_PCI is not set
 | |
| +# CONFIG_USB_CHIPIDEA_TEGRA is not set
 | |
| +# CONFIG_USB_CONFIGFS is not set
 | |
| +# CONFIG_USB_CONN_GPIO is not set
 | |
| +# CONFIG_USB_CXACRU is not set
 | |
| +# CONFIG_USB_CYPRESS_CY7C63 is not set
 | |
| +# CONFIG_USB_CYTHERM is not set
 | |
| +CONFIG_USB_DEFAULT_PERSIST=y
 | |
| +# CONFIG_USB_DSBR is not set
 | |
| +# CONFIG_USB_DUMMY_HCD is not set
 | |
| +# CONFIG_USB_DWC2 is not set
 | |
| +# CONFIG_USB_DWC2_DEBUG is not set
 | |
| +# CONFIG_USB_DWC2_DUAL_ROLE is not set
 | |
| +# CONFIG_USB_DWC2_HOST is not set
 | |
| +# CONFIG_USB_DWC2_PERIPHERAL is not set
 | |
| +# CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set
 | |
| +# CONFIG_USB_DWC3 is not set
 | |
| +# CONFIG_USB_DWC3_EXYNOS is not set
 | |
| +# CONFIG_USB_DWC3_HAPS is not set
 | |
| +# CONFIG_USB_DWC3_KEYSTONE is not set
 | |
| +# CONFIG_USB_DWC3_OF_SIMPLE is not set
 | |
| +# CONFIG_USB_DWC3_PCI is not set
 | |
| +# CONFIG_USB_DWC3_QCOM is not set
 | |
| +# CONFIG_USB_DWC3_ULPI is not set
 | |
| +# CONFIG_USB_DYNAMIC_MINORS is not set
 | |
| +# CONFIG_USB_EG20T is not set
 | |
| +# CONFIG_USB_EHCI_ATH79 is not set
 | |
| +# CONFIG_USB_EHCI_FSL is not set
 | |
| +# CONFIG_USB_EHCI_HCD is not set
 | |
| +# CONFIG_USB_EHCI_HCD_AT91 is not set
 | |
| +# CONFIG_USB_EHCI_HCD_OMAP is not set
 | |
| +# CONFIG_USB_EHCI_HCD_PPC_OF is not set
 | |
| +# CONFIG_USB_EHCI_MSM is not set
 | |
| +# CONFIG_USB_EHCI_MV is not set
 | |
| +CONFIG_USB_EHCI_ROOT_HUB_TT=y
 | |
| +CONFIG_USB_EHCI_TT_NEWSCHED=y
 | |
| +# CONFIG_USB_EHSET_TEST_FIXTURE is not set
 | |
| +# CONFIG_USB_EMI26 is not set
 | |
| +# CONFIG_USB_EMI62 is not set
 | |
| +# CONFIG_USB_EPSON2888 is not set
 | |
| +# CONFIG_USB_EZUSB_FX2 is not set
 | |
| +# CONFIG_USB_FEW_INIT_RETRIES is not set
 | |
| +# CONFIG_USB_FOTG210_HCD is not set
 | |
| +# CONFIG_USB_FOTG210_UDC is not set
 | |
| +# CONFIG_USB_FSL_USB2 is not set
 | |
| +# CONFIG_USB_FTDI_ELAN is not set
 | |
| +# CONFIG_USB_FUNCTIONFS is not set
 | |
| +# CONFIG_USB_FUSB300 is not set
 | |
| +# CONFIG_USB_GADGET is not set
 | |
| +# CONFIG_USB_GADGETFS is not set
 | |
| +# CONFIG_USB_GADGET_DEBUG is not set
 | |
| +# CONFIG_USB_GADGET_DEBUG_FILES is not set
 | |
| +# CONFIG_USB_GADGET_DEBUG_FS is not set
 | |
| +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
 | |
| +CONFIG_USB_GADGET_VBUS_DRAW=2
 | |
| +# CONFIG_USB_GADGET_XILINX is not set
 | |
| +# CONFIG_USB_GL860 is not set
 | |
| +# CONFIG_USB_GOKU is not set
 | |
| +# CONFIG_USB_GPIO_VBUS is not set
 | |
| +# CONFIG_USB_GR_UDC is not set
 | |
| +# CONFIG_USB_GSPCA is not set
 | |
| +# CONFIG_USB_GSPCA_BENQ is not set
 | |
| +# CONFIG_USB_GSPCA_CONEX is not set
 | |
| +# CONFIG_USB_GSPCA_CPIA1 is not set
 | |
| +# CONFIG_USB_GSPCA_DTCS033 is not set
 | |
| +# CONFIG_USB_GSPCA_ETOMS is not set
 | |
| +# CONFIG_USB_GSPCA_FINEPIX is not set
 | |
| +# CONFIG_USB_GSPCA_JEILINJ is not set
 | |
| +# CONFIG_USB_GSPCA_JL2005BCD is not set
 | |
| +# CONFIG_USB_GSPCA_KINECT is not set
 | |
| +# CONFIG_USB_GSPCA_KONICA is not set
 | |
| +# CONFIG_USB_GSPCA_MARS is not set
 | |
| +# CONFIG_USB_GSPCA_MR97310A is not set
 | |
| +# CONFIG_USB_GSPCA_NW80X is not set
 | |
| +# CONFIG_USB_GSPCA_OV519 is not set
 | |
| +# CONFIG_USB_GSPCA_OV534 is not set
 | |
| +# CONFIG_USB_GSPCA_OV534_9 is not set
 | |
| +# CONFIG_USB_GSPCA_PAC207 is not set
 | |
| +# CONFIG_USB_GSPCA_PAC7302 is not set
 | |
| +# CONFIG_USB_GSPCA_PAC7311 is not set
 | |
| +# CONFIG_USB_GSPCA_SE401 is not set
 | |
| +# CONFIG_USB_GSPCA_SN9C2028 is not set
 | |
| +# CONFIG_USB_GSPCA_SN9C20X is not set
 | |
| +# CONFIG_USB_GSPCA_SONIXB is not set
 | |
| +# CONFIG_USB_GSPCA_SONIXJ is not set
 | |
| +# CONFIG_USB_GSPCA_SPCA1528 is not set
 | |
| +# CONFIG_USB_GSPCA_SPCA500 is not set
 | |
| +# CONFIG_USB_GSPCA_SPCA501 is not set
 | |
| +# CONFIG_USB_GSPCA_SPCA505 is not set
 | |
| +# CONFIG_USB_GSPCA_SPCA506 is not set
 | |
| +# CONFIG_USB_GSPCA_SPCA508 is not set
 | |
| +# CONFIG_USB_GSPCA_SPCA561 is not set
 | |
| +# CONFIG_USB_GSPCA_SQ905 is not set
 | |
| +# CONFIG_USB_GSPCA_SQ905C is not set
 | |
| +# CONFIG_USB_GSPCA_SQ930X is not set
 | |
| +# CONFIG_USB_GSPCA_STK014 is not set
 | |
| +# CONFIG_USB_GSPCA_STK1135 is not set
 | |
| +# CONFIG_USB_GSPCA_STV0680 is not set
 | |
| +# CONFIG_USB_GSPCA_SUNPLUS is not set
 | |
| +# CONFIG_USB_GSPCA_T613 is not set
 | |
| +# CONFIG_USB_GSPCA_TOPRO is not set
 | |
| +# CONFIG_USB_GSPCA_TOUPTEK is not set
 | |
| +# CONFIG_USB_GSPCA_TV8532 is not set
 | |
| +# CONFIG_USB_GSPCA_VC032X is not set
 | |
| +# CONFIG_USB_GSPCA_VICAM is not set
 | |
| +# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
 | |
| +# CONFIG_USB_GSPCA_ZC3XX is not set
 | |
| +# CONFIG_USB_G_ACM_MS is not set
 | |
| +# CONFIG_USB_G_DBGP is not set
 | |
| +# CONFIG_USB_G_HID is not set
 | |
| +# CONFIG_USB_G_MULTI is not set
 | |
| +# CONFIG_USB_G_NCM is not set
 | |
| +# CONFIG_USB_G_NOKIA is not set
 | |
| +# CONFIG_USB_G_PRINTER is not set
 | |
| +# CONFIG_USB_G_SERIAL is not set
 | |
| +# CONFIG_USB_G_WEBCAM is not set
 | |
| +# CONFIG_USB_HACKRF is not set
 | |
| +# CONFIG_USB_HCD_TEST_MODE is not set
 | |
| +# CONFIG_USB_HID is not set
 | |
| +# CONFIG_USB_HIDDEV is not set
 | |
| +# CONFIG_USB_HSIC_USB3503 is not set
 | |
| +# CONFIG_USB_HSIC_USB4604 is not set
 | |
| +# CONFIG_USB_HSO is not set
 | |
| +# CONFIG_USB_HUB_USB251XB is not set
 | |
| +# CONFIG_USB_HWA_HCD is not set
 | |
| +# CONFIG_USB_IDMOUSE is not set
 | |
| +# CONFIG_USB_IMX21_HCD is not set
 | |
| +# CONFIG_USB_IOWARRIOR is not set
 | |
| +# CONFIG_USB_IPHETH is not set
 | |
| +# CONFIG_USB_ISIGHTFW is not set
 | |
| +# CONFIG_USB_ISP116X_HCD is not set
 | |
| +# CONFIG_USB_ISP1301 is not set
 | |
| +# CONFIG_USB_ISP1362_HCD is not set
 | |
| +# CONFIG_USB_ISP1760 is not set
 | |
| +# CONFIG_USB_ISP1760_HCD is not set
 | |
| +# CONFIG_USB_KAWETH is not set
 | |
| +# CONFIG_USB_KBD is not set
 | |
| +# CONFIG_USB_KC2190 is not set
 | |
| +# CONFIG_USB_LAN78XX is not set
 | |
| +# CONFIG_USB_LCD is not set
 | |
| +# CONFIG_USB_LD is not set
 | |
| +# CONFIG_USB_LED is not set
 | |
| +# CONFIG_USB_LEDS_TRIGGER_USBPORT is not set
 | |
| +# CONFIG_USB_LED_TRIG is not set
 | |
| +# CONFIG_USB_LEGOTOWER is not set
 | |
| +# CONFIG_USB_LGM_PHY is not set
 | |
| +# CONFIG_USB_LINK_LAYER_TEST is not set
 | |
| +# CONFIG_USB_M5602 is not set
 | |
| +# CONFIG_USB_M66592 is not set
 | |
| +# CONFIG_USB_MASS_STORAGE is not set
 | |
| +# CONFIG_USB_MAX3420_UDC is not set
 | |
| +# CONFIG_USB_MAX3421_HCD is not set
 | |
| +# CONFIG_USB_MDC800 is not set
 | |
| +# CONFIG_USB_MICROTEK is not set
 | |
| +# CONFIG_USB_MIDI_GADGET is not set
 | |
| +# CONFIG_USB_MON is not set
 | |
| +# CONFIG_USB_MOUSE is not set
 | |
| +# CONFIG_USB_MSI2500 is not set
 | |
| +# CONFIG_USB_MSM_OTG is not set
 | |
| +# CONFIG_USB_MTU3 is not set
 | |
| +# CONFIG_USB_MUSB_HDRC is not set
 | |
| +# CONFIG_USB_MV_U3D is not set
 | |
| +# CONFIG_USB_MV_UDC is not set
 | |
| +# CONFIG_USB_MXS_PHY is not set
 | |
| +# CONFIG_USB_NET2272 is not set
 | |
| +# CONFIG_USB_NET2280 is not set
 | |
| +# CONFIG_USB_NET_AQC111 is not set
 | |
| +# CONFIG_USB_NET_AX88179_178A is not set
 | |
| +# CONFIG_USB_NET_AX8817X is not set
 | |
| +# CONFIG_USB_NET_CDCETHER is not set
 | |
| +# CONFIG_USB_NET_CDC_EEM is not set
 | |
| +# CONFIG_USB_NET_CDC_MBIM is not set
 | |
| +# CONFIG_USB_NET_CDC_NCM is not set
 | |
| +# CONFIG_USB_NET_CDC_SUBSET is not set
 | |
| +# CONFIG_USB_NET_CH9200 is not set
 | |
| +# CONFIG_USB_NET_CX82310_ETH is not set
 | |
| +# CONFIG_USB_NET_DM9601 is not set
 | |
| +# CONFIG_USB_NET_DRIVERS is not set
 | |
| +# CONFIG_USB_NET_GL620A is not set
 | |
| +# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
 | |
| +# CONFIG_USB_NET_INT51X1 is not set
 | |
| +# CONFIG_USB_NET_KALMIA is not set
 | |
| +# CONFIG_USB_NET_MCS7830 is not set
 | |
| +# CONFIG_USB_NET_NET1080 is not set
 | |
| +# CONFIG_USB_NET_PLUSB is not set
 | |
| +# CONFIG_USB_NET_QMI_WWAN is not set
 | |
| +# CONFIG_USB_NET_RNDIS_HOST is not set
 | |
| +# CONFIG_USB_NET_RNDIS_WLAN is not set
 | |
| +# CONFIG_USB_NET_SMSC75XX is not set
 | |
| +# CONFIG_USB_NET_SMSC95XX is not set
 | |
| +# CONFIG_USB_NET_SR9700 is not set
 | |
| +# CONFIG_USB_NET_SR9800 is not set
 | |
| +# CONFIG_USB_NET_ZAURUS is not set
 | |
| +# CONFIG_USB_OHCI_HCD is not set
 | |
| +# CONFIG_USB_OHCI_HCD_PCI is not set
 | |
| +# CONFIG_USB_OHCI_HCD_PPC_OF is not set
 | |
| +# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
 | |
| +# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
 | |
| +# CONFIG_USB_OHCI_HCD_SSB is not set
 | |
| +CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 | |
| +# CONFIG_USB_OTG is not set
 | |
| +# CONFIG_USB_OTG_BLACKLIST_HUB is not set
 | |
| +# CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB is not set
 | |
| +# CONFIG_USB_OTG_FSM is not set
 | |
| +# CONFIG_USB_OTG_PRODUCTLIST is not set
 | |
| +# CONFIG_USB_OTG_WHITELIST is not set
 | |
| +# CONFIG_USB_OXU210HP_HCD is not set
 | |
| +# CONFIG_USB_PCI is not set
 | |
| +# CONFIG_USB_PEGASUS is not set
 | |
| +# CONFIG_USB_PHY is not set
 | |
| +# CONFIG_USB_PRINTER is not set
 | |
| +# CONFIG_USB_PWC_INPUT_EVDEV is not set
 | |
| +# CONFIG_USB_PXA27X is not set
 | |
| +# CONFIG_USB_R8A66597 is not set
 | |
| +# CONFIG_USB_R8A66597_HCD is not set
 | |
| +# CONFIG_USB_RAW_GADGET is not set
 | |
| +# CONFIG_USB_RCAR_PHY is not set
 | |
| +# CONFIG_USB_RENESAS_USBHS is not set
 | |
| +# CONFIG_USB_RIO500 is not set
 | |
| +# CONFIG_USB_ROLES_INTEL_XHCI is not set
 | |
| +# CONFIG_USB_ROLE_SWITCH is not set
 | |
| +# CONFIG_USB_RTL8150 is not set
 | |
| +# CONFIG_USB_RTL8152 is not set
 | |
| +# CONFIG_USB_S2255 is not set
 | |
| +# CONFIG_USB_SERIAL is not set
 | |
| +# CONFIG_USB_SERIAL_AIRCABLE is not set
 | |
| +# CONFIG_USB_SERIAL_ARK3116 is not set
 | |
| +# CONFIG_USB_SERIAL_BELKIN is not set
 | |
| +# CONFIG_USB_SERIAL_CH341 is not set
 | |
| +# CONFIG_USB_SERIAL_CP210X is not set
 | |
| +# CONFIG_USB_SERIAL_CYBERJACK is not set
 | |
| +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 | |
| +# CONFIG_USB_SERIAL_DEBUG is not set
 | |
| +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
 | |
| +# CONFIG_USB_SERIAL_EDGEPORT is not set
 | |
| +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
 | |
| +# CONFIG_USB_SERIAL_EMPEG is not set
 | |
| +# CONFIG_USB_SERIAL_F81232 is not set
 | |
| +# CONFIG_USB_SERIAL_F8153X is not set
 | |
| +# CONFIG_USB_SERIAL_FTDI_SIO is not set
 | |
| +# CONFIG_USB_SERIAL_GARMIN is not set
 | |
| +CONFIG_USB_SERIAL_GENERIC=y
 | |
| +# CONFIG_USB_SERIAL_IPAQ is not set
 | |
| +# CONFIG_USB_SERIAL_IPW is not set
 | |
| +# CONFIG_USB_SERIAL_IR is not set
 | |
| +# CONFIG_USB_SERIAL_IUU is not set
 | |
| +# CONFIG_USB_SERIAL_KEYSPAN is not set
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_MPR=y
 | |
| +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA19=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA28=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
 | |
| +CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 | |
| +# CONFIG_USB_SERIAL_KLSI is not set
 | |
| +# CONFIG_USB_SERIAL_KOBIL_SCT is not set
 | |
| +# CONFIG_USB_SERIAL_MCT_U232 is not set
 | |
| +# CONFIG_USB_SERIAL_METRO is not set
 | |
| +# CONFIG_USB_SERIAL_MOS7715_PARPORT is not set
 | |
| +# CONFIG_USB_SERIAL_MOS7720 is not set
 | |
| +# CONFIG_USB_SERIAL_MOS7840 is not set
 | |
| +# CONFIG_USB_SERIAL_MXUPORT is not set
 | |
| +# CONFIG_USB_SERIAL_NAVMAN is not set
 | |
| +# CONFIG_USB_SERIAL_OMNINET is not set
 | |
| +# CONFIG_USB_SERIAL_OPTICON is not set
 | |
| +# CONFIG_USB_SERIAL_OPTION is not set
 | |
| +# CONFIG_USB_SERIAL_OTI6858 is not set
 | |
| +# CONFIG_USB_SERIAL_PL2303 is not set
 | |
| +# CONFIG_USB_SERIAL_QCAUX is not set
 | |
| +# CONFIG_USB_SERIAL_QT2 is not set
 | |
| +# CONFIG_USB_SERIAL_QUALCOMM is not set
 | |
| +# CONFIG_USB_SERIAL_SAFE is not set
 | |
| +CONFIG_USB_SERIAL_SAFE_PADDED=y
 | |
| +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 | |
| +# CONFIG_USB_SERIAL_SIMPLE is not set
 | |
| +# CONFIG_USB_SERIAL_SPCP8X5 is not set
 | |
| +# CONFIG_USB_SERIAL_SSU100 is not set
 | |
| +# CONFIG_USB_SERIAL_SYMBOL is not set
 | |
| +# CONFIG_USB_SERIAL_TI is not set
 | |
| +# CONFIG_USB_SERIAL_UPD78F0730 is not set
 | |
| +# CONFIG_USB_SERIAL_VISOR is not set
 | |
| +# CONFIG_USB_SERIAL_WHITEHEAT is not set
 | |
| +# CONFIG_USB_SERIAL_WISHBONE is not set
 | |
| +# CONFIG_USB_SERIAL_XIRCOM is not set
 | |
| +# CONFIG_USB_SERIAL_XSENS_MT is not set
 | |
| +# CONFIG_USB_SEVSEG is not set
 | |
| +# CONFIG_USB_SIERRA_NET is not set
 | |
| +# CONFIG_USB_SISUSBVGA is not set
 | |
| +# CONFIG_USB_SL811_HCD is not set
 | |
| +# CONFIG_USB_SNP_UDC_PLAT is not set
 | |
| +# CONFIG_USB_SPEEDTOUCH is not set
 | |
| +# CONFIG_USB_STKWEBCAM is not set
 | |
| +# CONFIG_USB_STORAGE is not set
 | |
| +# CONFIG_USB_STORAGE_ALAUDA is not set
 | |
| +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 | |
| +# CONFIG_USB_STORAGE_DATAFAB is not set
 | |
| +# CONFIG_USB_STORAGE_DEBUG is not set
 | |
| +# CONFIG_USB_STORAGE_ENE_UB6250 is not set
 | |
| +# CONFIG_USB_STORAGE_FREECOM is not set
 | |
| +# CONFIG_USB_STORAGE_ISD200 is not set
 | |
| +# CONFIG_USB_STORAGE_JUMPSHOT is not set
 | |
| +# CONFIG_USB_STORAGE_KARMA is not set
 | |
| +# CONFIG_USB_STORAGE_ONETOUCH is not set
 | |
| +# CONFIG_USB_STORAGE_REALTEK is not set
 | |
| +# CONFIG_USB_STORAGE_SDDR09 is not set
 | |
| +# CONFIG_USB_STORAGE_SDDR55 is not set
 | |
| +# CONFIG_USB_STORAGE_USBAT is not set
 | |
| +# CONFIG_USB_STV06XX is not set
 | |
| +# CONFIG_USB_SUPPORT is not set
 | |
| +# CONFIG_USB_SWITCH_FSA9480 is not set
 | |
| +# CONFIG_USB_TEST is not set
 | |
| +# CONFIG_USB_TMC is not set
 | |
| +# CONFIG_USB_TRANCEVIBRATOR is not set
 | |
| +# CONFIG_USB_UAS is not set
 | |
| +# CONFIG_USB_UEAGLEATM is not set
 | |
| +# CONFIG_USB_ULPI is not set
 | |
| +# CONFIG_USB_ULPI_BUS is not set
 | |
| +# CONFIG_USB_USBNET is not set
 | |
| +# CONFIG_USB_USS720 is not set
 | |
| +# CONFIG_USB_VIDEO_CLASS is not set
 | |
| +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
 | |
| +# CONFIG_USB_VL600 is not set
 | |
| +# CONFIG_USB_WDM is not set
 | |
| +# CONFIG_USB_WHCI_HCD is not set
 | |
| +# CONFIG_USB_WUSB is not set
 | |
| +# CONFIG_USB_WUSB_CBAF is not set
 | |
| +# CONFIG_USB_XHCI_DBGCAP is not set
 | |
| +# CONFIG_USB_XHCI_HCD is not set
 | |
| +# CONFIG_USB_XHCI_MVEBU is not set
 | |
| +# CONFIG_USB_XHCI_PCI_RENESAS is not set
 | |
| +# CONFIG_USB_XUSBATM is not set
 | |
| +# CONFIG_USB_YUREX is not set
 | |
| +# CONFIG_USB_ZD1201 is not set
 | |
| +# CONFIG_USB_ZERO is not set
 | |
| +# CONFIG_USB_ZR364XX is not set
 | |
| +# CONFIG_USELIB is not set
 | |
| +# CONFIG_USERFAULTFD is not set
 | |
| +# CONFIG_USERIO is not set
 | |
| +# CONFIG_USE_OF is not set
 | |
| +# CONFIG_UTS_NS is not set
 | |
| +# CONFIG_UWB is not set
 | |
| +# CONFIG_U_SERIAL_CONSOLE is not set
 | |
| +# CONFIG_V4L_MEM2MEM_DRIVERS is not set
 | |
| +# CONFIG_V4L_PLATFORM_DRIVERS is not set
 | |
| +# CONFIG_V4L_TEST_DRIVERS is not set
 | |
| +# CONFIG_VALIDATE_FS_PARSER is not set
 | |
| +# CONFIG_VBOXGUEST is not set
 | |
| +# CONFIG_VCNL3020 is not set
 | |
| +# CONFIG_VCNL4000 is not set
 | |
| +# CONFIG_VCNL4035 is not set
 | |
| +# CONFIG_VDPA is not set
 | |
| +CONFIG_VDSO=y
 | |
| +# CONFIG_VEML6030 is not set
 | |
| +# CONFIG_VEML6070 is not set
 | |
| +# CONFIG_VETH is not set
 | |
| +# CONFIG_VEXPRESS_CONFIG is not set
 | |
| +# CONFIG_VF610_ADC is not set
 | |
| +# CONFIG_VF610_DAC is not set
 | |
| +# CONFIG_VFAT_FS is not set
 | |
| +# CONFIG_VFIO is not set
 | |
| +# CONFIG_VGASTATE is not set
 | |
| +# CONFIG_VGA_ARB is not set
 | |
| +# CONFIG_VGA_SWITCHEROO is not set
 | |
| +# CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set
 | |
| +CONFIG_VHOST_MENU=y
 | |
| +# CONFIG_VHOST_NET is not set
 | |
| +# CONFIG_VHOST_VSOCK is not set
 | |
| +# CONFIG_VIA_RHINE is not set
 | |
| +# CONFIG_VIA_VELOCITY is not set
 | |
| +# CONFIG_VIDEO_AD5820 is not set
 | |
| +# CONFIG_VIDEO_AD9389B is not set
 | |
| +# CONFIG_VIDEO_ADP1653 is not set
 | |
| +# CONFIG_VIDEO_ADV7170 is not set
 | |
| +# CONFIG_VIDEO_ADV7175 is not set
 | |
| +# CONFIG_VIDEO_ADV7180 is not set
 | |
| +# CONFIG_VIDEO_ADV7183 is not set
 | |
| +# CONFIG_VIDEO_ADV7343 is not set
 | |
| +# CONFIG_VIDEO_ADV7393 is not set
 | |
| +# CONFIG_VIDEO_ADV748X is not set
 | |
| +# CONFIG_VIDEO_ADV7511 is not set
 | |
| +# CONFIG_VIDEO_ADV7604 is not set
 | |
| +# CONFIG_VIDEO_ADV7842 is not set
 | |
| +# CONFIG_VIDEO_ADV_DEBUG is not set
 | |
| +# CONFIG_VIDEO_AK7375 is not set
 | |
| +# CONFIG_VIDEO_AK881X is not set
 | |
| +# CONFIG_VIDEO_ASPEED is not set
 | |
| +# CONFIG_VIDEO_AU0828 is not set
 | |
| +# CONFIG_VIDEO_BT819 is not set
 | |
| +# CONFIG_VIDEO_BT848 is not set
 | |
| +# CONFIG_VIDEO_BT856 is not set
 | |
| +# CONFIG_VIDEO_BT866 is not set
 | |
| +# CONFIG_VIDEO_CADENCE is not set
 | |
| +# CONFIG_VIDEO_CAFE_CCIC is not set
 | |
| +# CONFIG_VIDEO_CS3308 is not set
 | |
| +# CONFIG_VIDEO_CS5345 is not set
 | |
| +# CONFIG_VIDEO_CS53L32A is not set
 | |
| +# CONFIG_VIDEO_CX231XX is not set
 | |
| +# CONFIG_VIDEO_CX2341X is not set
 | |
| +# CONFIG_VIDEO_CX25840 is not set
 | |
| +# CONFIG_VIDEO_CX88 is not set
 | |
| +# CONFIG_VIDEO_DEV is not set
 | |
| +# CONFIG_VIDEO_DM6446_CCDC is not set
 | |
| +# CONFIG_VIDEO_DT3155 is not set
 | |
| +# CONFIG_VIDEO_DW9714 is not set
 | |
| +# CONFIG_VIDEO_DW9768 is not set
 | |
| +# CONFIG_VIDEO_DW9807_VCM is not set
 | |
| +# CONFIG_VIDEO_EM28XX is not set
 | |
| +# CONFIG_VIDEO_ET8EK8 is not set
 | |
| +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 | |
| +# CONFIG_VIDEO_GO7007 is not set
 | |
| +# CONFIG_VIDEO_GS1662 is not set
 | |
| +# CONFIG_VIDEO_HDPVR is not set
 | |
| +# CONFIG_VIDEO_HEXIUM_GEMINI is not set
 | |
| +# CONFIG_VIDEO_HEXIUM_ORION is not set
 | |
| +# CONFIG_VIDEO_HI556 is not set
 | |
| +# CONFIG_VIDEO_I2C is not set
 | |
| +# CONFIG_VIDEO_IMX214 is not set
 | |
| +# CONFIG_VIDEO_IMX219 is not set
 | |
| +# CONFIG_VIDEO_IMX258 is not set
 | |
| +# CONFIG_VIDEO_IMX274 is not set
 | |
| +# CONFIG_VIDEO_IMX290 is not set
 | |
| +# CONFIG_VIDEO_IMX319 is not set
 | |
| +# CONFIG_VIDEO_IMX355 is not set
 | |
| +# CONFIG_VIDEO_IR_I2C is not set
 | |
| +# CONFIG_VIDEO_IVTV is not set
 | |
| +# CONFIG_VIDEO_KS0127 is not set
 | |
| +# CONFIG_VIDEO_LM3560 is not set
 | |
| +# CONFIG_VIDEO_LM3646 is not set
 | |
| +# CONFIG_VIDEO_M52790 is not set
 | |
| +# CONFIG_VIDEO_M5MOLS is not set
 | |
| +# CONFIG_VIDEO_MAX9286 is not set
 | |
| +# CONFIG_VIDEO_ML86V7667 is not set
 | |
| +# CONFIG_VIDEO_MSP3400 is not set
 | |
| +# CONFIG_VIDEO_MT9M001 is not set
 | |
| +# CONFIG_VIDEO_MT9M032 is not set
 | |
| +# CONFIG_VIDEO_MT9M111 is not set
 | |
| +# CONFIG_VIDEO_MT9P031 is not set
 | |
| +# CONFIG_VIDEO_MT9T001 is not set
 | |
| +# CONFIG_VIDEO_MT9T112 is not set
 | |
| +# CONFIG_VIDEO_MT9V011 is not set
 | |
| +# CONFIG_VIDEO_MT9V032 is not set
 | |
| +# CONFIG_VIDEO_MT9V111 is not set
 | |
| +# CONFIG_VIDEO_MUX is not set
 | |
| +# CONFIG_VIDEO_MXB is not set
 | |
| +# CONFIG_VIDEO_NOON010PC30 is not set
 | |
| +# CONFIG_VIDEO_OMAP2_VOUT is not set
 | |
| +# CONFIG_VIDEO_OV13858 is not set
 | |
| +# CONFIG_VIDEO_OV2640 is not set
 | |
| +# CONFIG_VIDEO_OV2659 is not set
 | |
| +# CONFIG_VIDEO_OV2680 is not set
 | |
| +# CONFIG_VIDEO_OV2685 is not set
 | |
| +# CONFIG_VIDEO_OV2740 is not set
 | |
| +# CONFIG_VIDEO_OV5640 is not set
 | |
| +# CONFIG_VIDEO_OV5645 is not set
 | |
| +# CONFIG_VIDEO_OV5647 is not set
 | |
| +# CONFIG_VIDEO_OV5670 is not set
 | |
| +# CONFIG_VIDEO_OV5675 is not set
 | |
| +# CONFIG_VIDEO_OV5695 is not set
 | |
| +# CONFIG_VIDEO_OV6650 is not set
 | |
| +# CONFIG_VIDEO_OV7251 is not set
 | |
| +# CONFIG_VIDEO_OV7640 is not set
 | |
| +# CONFIG_VIDEO_OV7670 is not set
 | |
| +# CONFIG_VIDEO_OV772X is not set
 | |
| +# CONFIG_VIDEO_OV7740 is not set
 | |
| +# CONFIG_VIDEO_OV8856 is not set
 | |
| +# CONFIG_VIDEO_OV9640 is not set
 | |
| +# CONFIG_VIDEO_OV9650 is not set
 | |
| +# CONFIG_VIDEO_PVRUSB2 is not set
 | |
| +# CONFIG_VIDEO_RDACM20 is not set
 | |
| +# CONFIG_VIDEO_RJ54N1 is not set
 | |
| +# CONFIG_VIDEO_S5C73M3 is not set
 | |
| +# CONFIG_VIDEO_S5K4ECGX is not set
 | |
| +# CONFIG_VIDEO_S5K5BAF is not set
 | |
| +# CONFIG_VIDEO_S5K6A3 is not set
 | |
| +# CONFIG_VIDEO_S5K6AA is not set
 | |
| +# CONFIG_VIDEO_SAA6588 is not set
 | |
| +# CONFIG_VIDEO_SAA6752HS is not set
 | |
| +# CONFIG_VIDEO_SAA7110 is not set
 | |
| +# CONFIG_VIDEO_SAA711X is not set
 | |
| +# CONFIG_VIDEO_SAA7127 is not set
 | |
| +# CONFIG_VIDEO_SAA7134 is not set
 | |
| +# CONFIG_VIDEO_SAA717X is not set
 | |
| +# CONFIG_VIDEO_SAA7185 is not set
 | |
| +# CONFIG_VIDEO_SH_MOBILE_CEU is not set
 | |
| +# CONFIG_VIDEO_SMIAPP is not set
 | |
| +# CONFIG_VIDEO_SONY_BTF_MPX is not set
 | |
| +# CONFIG_VIDEO_SR030PC30 is not set
 | |
| +# CONFIG_VIDEO_STK1160_COMMON is not set
 | |
| +# CONFIG_VIDEO_ST_MIPID02 is not set
 | |
| +# CONFIG_VIDEO_TC358743 is not set
 | |
| +# CONFIG_VIDEO_TDA1997X is not set
 | |
| +# CONFIG_VIDEO_TDA7432 is not set
 | |
| +# CONFIG_VIDEO_TDA9840 is not set
 | |
| +# CONFIG_VIDEO_TEA6415C is not set
 | |
| +# CONFIG_VIDEO_TEA6420 is not set
 | |
| +# CONFIG_VIDEO_THS7303 is not set
 | |
| +# CONFIG_VIDEO_THS8200 is not set
 | |
| +# CONFIG_VIDEO_TIMBERDALE is not set
 | |
| +# CONFIG_VIDEO_TLV320AIC23B is not set
 | |
| +# CONFIG_VIDEO_TM6000 is not set
 | |
| +# CONFIG_VIDEO_TVAUDIO is not set
 | |
| +# CONFIG_VIDEO_TVP514X is not set
 | |
| +# CONFIG_VIDEO_TVP5150 is not set
 | |
| +# CONFIG_VIDEO_TVP7002 is not set
 | |
| +# CONFIG_VIDEO_TW2804 is not set
 | |
| +# CONFIG_VIDEO_TW9903 is not set
 | |
| +# CONFIG_VIDEO_TW9906 is not set
 | |
| +# CONFIG_VIDEO_TW9910 is not set
 | |
| +# CONFIG_VIDEO_UDA1342 is not set
 | |
| +# CONFIG_VIDEO_UPD64031A is not set
 | |
| +# CONFIG_VIDEO_UPD64083 is not set
 | |
| +# CONFIG_VIDEO_USBTV is not set
 | |
| +# CONFIG_VIDEO_USBVISION is not set
 | |
| +# CONFIG_VIDEO_V4L2 is not set
 | |
| +# CONFIG_VIDEO_VP27SMPX is not set
 | |
| +# CONFIG_VIDEO_VPX3220 is not set
 | |
| +# CONFIG_VIDEO_VS6624 is not set
 | |
| +# CONFIG_VIDEO_WM8739 is not set
 | |
| +# CONFIG_VIDEO_WM8775 is not set
 | |
| +# CONFIG_VIDEO_XILINX is not set
 | |
| +# CONFIG_VIDEO_ZORAN is not set
 | |
| +# CONFIG_VIRTIO_BALLOON is not set
 | |
| +# CONFIG_VIRTIO_BLK_SCSI is not set
 | |
| +# CONFIG_VIRTIO_CONSOLE is not set
 | |
| +# CONFIG_VIRTIO_FS is not set
 | |
| +# CONFIG_VIRTIO_INPUT is not set
 | |
| +CONFIG_VIRTIO_MENU=y
 | |
| +# CONFIG_VIRTIO_MMIO is not set
 | |
| +# CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES is not set
 | |
| +# CONFIG_VIRTIO_PCI is not set
 | |
| +# CONFIG_VIRTUALIZATION is not set
 | |
| +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
 | |
| +# CONFIG_VIRT_DRIVERS is not set
 | |
| +CONFIG_VIRT_TO_BUS=y
 | |
| +# CONFIG_VITESSE_PHY is not set
 | |
| +# CONFIG_VL53L0X_I2C is not set
 | |
| +# CONFIG_VL6180 is not set
 | |
| +CONFIG_VLAN_8021Q=y
 | |
| +# CONFIG_VLAN_8021Q_GVRP is not set
 | |
| +# CONFIG_VLAN_8021Q_MVRP is not set
 | |
| +# CONFIG_VME_BUS is not set
 | |
| +# CONFIG_VMSPLIT_1G is not set
 | |
| +# CONFIG_VMSPLIT_2G is not set
 | |
| +# CONFIG_VMSPLIT_2G_OPT is not set
 | |
| +CONFIG_VMSPLIT_3G=y
 | |
| +# CONFIG_VMSPLIT_3G_OPT is not set
 | |
| +# CONFIG_VMWARE_PVSCSI is not set
 | |
| +# CONFIG_VMXNET3 is not set
 | |
| +# CONFIG_VM_EVENT_COUNTERS is not set
 | |
| +# CONFIG_VOP_BUS is not set
 | |
| +# CONFIG_VORTEX is not set
 | |
| +# CONFIG_VSOCKETS is not set
 | |
| +# CONFIG_VSOCKETS_DIAG is not set
 | |
| +# CONFIG_VT is not set
 | |
| +# CONFIG_VT6655 is not set
 | |
| +# CONFIG_VT6656 is not set
 | |
| +# CONFIG_VXFS_FS is not set
 | |
| +# CONFIG_VXGE is not set
 | |
| +# CONFIG_VXLAN is not set
 | |
| +# CONFIG_VZ89X is not set
 | |
| +# CONFIG_W1 is not set
 | |
| +# CONFIG_W1_CON is not set
 | |
| +# CONFIG_W1_MASTER_DS1WM is not set
 | |
| +# CONFIG_W1_MASTER_DS2482 is not set
 | |
| +# CONFIG_W1_MASTER_DS2490 is not set
 | |
| +# CONFIG_W1_MASTER_GPIO is not set
 | |
| +# CONFIG_W1_MASTER_MATROX is not set
 | |
| +# CONFIG_W1_MASTER_SGI is not set
 | |
| +# CONFIG_W1_SLAVE_DS2405 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2406 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2408 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2413 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2423 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2430 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2431 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2433 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2438 is not set
 | |
| +# CONFIG_W1_SLAVE_DS250X is not set
 | |
| +# CONFIG_W1_SLAVE_DS2780 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2781 is not set
 | |
| +# CONFIG_W1_SLAVE_DS2805 is not set
 | |
| +# CONFIG_W1_SLAVE_DS28E04 is not set
 | |
| +# CONFIG_W1_SLAVE_DS28E17 is not set
 | |
| +# CONFIG_W1_SLAVE_SMEM is not set
 | |
| +# CONFIG_W1_SLAVE_THERM is not set
 | |
| +# CONFIG_W83627HF_WDT is not set
 | |
| +# CONFIG_W83877F_WDT is not set
 | |
| +# CONFIG_W83977F_WDT is not set
 | |
| +# CONFIG_WAN is not set
 | |
| +# CONFIG_WANXL is not set
 | |
| +# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
 | |
| +CONFIG_WATCHDOG=y
 | |
| +# CONFIG_WATCHDOG_CORE is not set
 | |
| +CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED=y
 | |
| +# CONFIG_WATCHDOG_NOWAYOUT is not set
 | |
| +CONFIG_WATCHDOG_OPEN_TIMEOUT=0
 | |
| +# CONFIG_WATCHDOG_PRETIMEOUT_GOV is not set
 | |
| +# CONFIG_WATCHDOG_SYSFS is not set
 | |
| +# CONFIG_WATCH_QUEUE is not set
 | |
| +# CONFIG_WD80x3 is not set
 | |
| +# CONFIG_WDAT_WDT is not set
 | |
| +# CONFIG_WDTPCI is not set
 | |
| +CONFIG_WEXT_CORE=y
 | |
| +CONFIG_WEXT_PRIV=y
 | |
| +CONFIG_WEXT_PROC=y
 | |
| +CONFIG_WEXT_SPY=y
 | |
| +CONFIG_WILINK_PLATFORM_DATA=y
 | |
| +# CONFIG_WIMAX is not set
 | |
| +# CONFIG_WIREGUARD is not set
 | |
| +CONFIG_WIRELESS=y
 | |
| +CONFIG_WIRELESS_EXT=y
 | |
| +# CONFIG_WIRELESS_WDS is not set
 | |
| +# CONFIG_WIZNET_W5100 is not set
 | |
| +# CONFIG_WIZNET_W5300 is not set
 | |
| +# CONFIG_WL1251 is not set
 | |
| +# CONFIG_WL12XX is not set
 | |
| +# CONFIG_WL18XX is not set
 | |
| +CONFIG_WLAN=y
 | |
| +# CONFIG_WLAN_VENDOR_ADMTEK is not set
 | |
| +# CONFIG_WLAN_VENDOR_ATH is not set
 | |
| +# CONFIG_WLAN_VENDOR_ATMEL is not set
 | |
| +# CONFIG_WLAN_VENDOR_BROADCOM is not set
 | |
| +# CONFIG_WLAN_VENDOR_CISCO is not set
 | |
| +# CONFIG_WLAN_VENDOR_INTEL is not set
 | |
| +# CONFIG_WLAN_VENDOR_INTERSIL is not set
 | |
| +# CONFIG_WLAN_VENDOR_MARVELL is not set
 | |
| +# CONFIG_WLAN_VENDOR_MEDIATEK is not set
 | |
| +# CONFIG_WLAN_VENDOR_MICROCHIP is not set
 | |
| +# CONFIG_WLAN_VENDOR_QUANTENNA is not set
 | |
| +# CONFIG_WLAN_VENDOR_RALINK is not set
 | |
| +# CONFIG_WLAN_VENDOR_REALTEK is not set
 | |
| +# CONFIG_WLAN_VENDOR_RSI is not set
 | |
| +# CONFIG_WLAN_VENDOR_ST is not set
 | |
| +# CONFIG_WLAN_VENDOR_TI is not set
 | |
| +# CONFIG_WLAN_VENDOR_ZYDAS is not set
 | |
| +# CONFIG_WLCORE is not set
 | |
| +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
 | |
| +# CONFIG_WQ_WATCHDOG is not set
 | |
| +# CONFIG_WW_MUTEX_SELFTEST is not set
 | |
| +# CONFIG_X25 is not set
 | |
| +# CONFIG_X509_CERTIFICATE_PARSER is not set
 | |
| +# CONFIG_X86_PKG_TEMP_THERMAL is not set
 | |
| +CONFIG_X86_SYSFB=y
 | |
| +# CONFIG_XDP_SOCKETS is not set
 | |
| +# CONFIG_XEN is not set
 | |
| +# CONFIG_XEN_GRANT_DMA_ALLOC is not set
 | |
| +# CONFIG_XEN_PVCALLS_FRONTEND is not set
 | |
| +CONFIG_XEN_SCRUB_PAGES_DEFAULT=y
 | |
| +CONFIG_XFRM=y
 | |
| +# CONFIG_XFRM_INTERFACE is not set
 | |
| +# CONFIG_XFRM_IPCOMP is not set
 | |
| +# CONFIG_XFRM_MIGRATE is not set
 | |
| +# CONFIG_XFRM_STATISTICS is not set
 | |
| +# CONFIG_XFRM_SUB_POLICY is not set
 | |
| +# CONFIG_XFRM_USER is not set
 | |
| +# CONFIG_XFS_DEBUG is not set
 | |
| +# CONFIG_XFS_FS is not set
 | |
| +# CONFIG_XFS_ONLINE_SCRUB is not set
 | |
| +# CONFIG_XFS_POSIX_ACL is not set
 | |
| +# CONFIG_XFS_QUOTA is not set
 | |
| +# CONFIG_XFS_RT is not set
 | |
| +# CONFIG_XFS_SUPPORT_V4 is not set
 | |
| +# CONFIG_XFS_WARN is not set
 | |
| +# CONFIG_XILINX_AXI_EMAC is not set
 | |
| +# CONFIG_XILINX_DMA is not set
 | |
| +# CONFIG_XILINX_EMACLITE is not set
 | |
| +# CONFIG_XILINX_GMII2RGMII is not set
 | |
| +# CONFIG_XILINX_LL_TEMAC is not set
 | |
| +# CONFIG_XILINX_SDFEC is not set
 | |
| +# CONFIG_XILINX_VCU is not set
 | |
| +# CONFIG_XILINX_WATCHDOG is not set
 | |
| +# CONFIG_XILINX_XADC is not set
 | |
| +# CONFIG_XILINX_ZYNQMP_DMA is not set
 | |
| +# CONFIG_XILINX_ZYNQMP_DPDMA is not set
 | |
| +# CONFIG_XILLYBUS is not set
 | |
| +# CONFIG_XIL_AXIS_FIFO is not set
 | |
| +# CONFIG_XIP_KERNEL is not set
 | |
| +# CONFIG_XMON is not set
 | |
| +CONFIG_XZ_DEC=y
 | |
| +# CONFIG_XZ_DEC_ARM is not set
 | |
| +# CONFIG_XZ_DEC_ARMTHUMB is not set
 | |
| +# CONFIG_XZ_DEC_BCJ is not set
 | |
| +# CONFIG_XZ_DEC_IA64 is not set
 | |
| +# CONFIG_XZ_DEC_POWERPC is not set
 | |
| +# CONFIG_XZ_DEC_SPARC is not set
 | |
| +# CONFIG_XZ_DEC_TEST is not set
 | |
| +# CONFIG_XZ_DEC_X86 is not set
 | |
| +# CONFIG_YAM is not set
 | |
| +# CONFIG_YELLOWFIN is not set
 | |
| +# CONFIG_YENTA is not set
 | |
| +# CONFIG_YENTA_O2 is not set
 | |
| +# CONFIG_YENTA_RICOH is not set
 | |
| +# CONFIG_YENTA_TI is not set
 | |
| +# CONFIG_YENTA_TOSHIBA is not set
 | |
| +# CONFIG_ZBUD is not set
 | |
| +# CONFIG_ZD1211RW is not set
 | |
| +# CONFIG_ZD1211RW_DEBUG is not set
 | |
| +# CONFIG_ZEROPLUS_FF is not set
 | |
| +# CONFIG_ZIIRAVE_WATCHDOG is not set
 | |
| +# CONFIG_ZISOFS is not set
 | |
| +# CONFIG_ZLIB_DEFLATE is not set
 | |
| +# CONFIG_ZLIB_INFLATE is not set
 | |
| +CONFIG_ZONE_DMA=y
 | |
| +# CONFIG_ZOPT2201 is not set
 | |
| +# CONFIG_ZPA2326 is not set
 | |
| +# CONFIG_ZPOOL is not set
 | |
| +# CONFIG_ZRAM is not set
 | |
| +# CONFIG_ZRAM_MEMORY_TRACKING is not set
 | |
| +# CONFIG_ZSMALLOC is not set
 | |
| +# CONFIG_ZX_TDM is not set
 | |
| diff --git a/target/linux/generic/config-5.4 b/target/linux/generic/config-5.4
 | |
| index 50e627297e..da0e2e2186 100644
 | |
| --- a/target/linux/generic/config-5.4
 | |
| +++ b/target/linux/generic/config-5.4
 | |
| @@ -3287,6 +3287,7 @@ CONFIG_MTD_ROOTFS_ROOT_DEV=y
 | |
|  CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT=4096
 | |
|  CONFIG_MTD_SPLIT=y
 | |
|  # CONFIG_MTD_SPLIT_BCM_WFI_FW is not set
 | |
| +# CONFIG_MTD_SPLIT_BCM63XX_FW is not set
 | |
|  # CONFIG_MTD_SPLIT_BRNIMAGE_FW is not set
 | |
|  # CONFIG_MTD_SPLIT_ELF_FW is not set
 | |
|  # CONFIG_MTD_SPLIT_EVA_FW is not set
 | |
| diff --git a/target/linux/generic/config-filter b/target/linux/generic/config-filter
 | |
| index 0d53ed9c3c..7d634b56cf 100644
 | |
| --- a/target/linux/generic/config-filter
 | |
| +++ b/target/linux/generic/config-filter
 | |
| @@ -1,7 +1,11 @@
 | |
| -# CONFIG_ARCH_(ENABLE|HAS|HAVE|INLINE|SUPPORTS|USE|WANT)_.* is not set
 | |
| +# CONFIG_ARM64_AS_.* is not set
 | |
| +# CONFIG_ARM64_CONT_.*_SHIFT is not set
 | |
| +# CONFIG_ARCH_(ENABLE|HAS|HAVE|INLINE|SUPPORTS|USE|WANT|STACKWALK)_.* is not set
 | |
|  # CONFIG_AS_.* is not set
 | |
|  # CONFIG_CC_(CAN|HAS|IS|VERSION)_.* is not set
 | |
|  # CONFIG_LD_.* is not set
 | |
|  # CONFIG_GCC_VERSION is not set
 | |
|  # CONFIG_INLINE_.* is not set
 | |
|  # CONFIG_HAVE_(?!(ARCH_TIMER|TCM|SMP)).* is not set
 | |
| +# CONFIG_SET_FS is not set
 | |
| +# CONFIG_TASKS_.* is not set
 | |
| diff --git a/target/linux/generic/files/block/partitions/fit.c b/target/linux/generic/files/block/partitions/fit.c
 | |
| new file mode 100644
 | |
| index 0000000000..c0d9642505
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/files/block/partitions/fit.c
 | |
| @@ -0,0 +1,254 @@
 | |
| +// SPDX-License-Identifier: GPL-2.0-or-later
 | |
| +/*
 | |
| + *  fs/partitions/fit.c
 | |
| + *  Copyright (C) 2021  Daniel Golle
 | |
| + *
 | |
| + *  headers extracted from U-Boot mkimage sources
 | |
| + *  (C) Copyright 2008 Semihalf
 | |
| + *  (C) Copyright 2000-2005
 | |
| + *  Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 | |
| + *
 | |
| + *  based on existing partition parsers
 | |
| + *  Copyright (C) 1991-1998  Linus Torvalds
 | |
| + *  Re-organised Feb 1998 Russell King
 | |
| + */
 | |
| +
 | |
| +#define pr_fmt(fmt) fmt
 | |
| +
 | |
| +#include <linux/types.h>
 | |
| +#include <linux/of.h>
 | |
| +#include <linux/of_device.h>
 | |
| +#include <linux/of_fdt.h>
 | |
| +#include <linux/libfdt.h>
 | |
| +
 | |
| +#include "check.h"
 | |
| +
 | |
| +#define FIT_IMAGES_PATH		"/images"
 | |
| +#define FIT_CONFS_PATH		"/configurations"
 | |
| +
 | |
| +/* hash/signature/key node */
 | |
| +#define FIT_HASH_NODENAME	"hash"
 | |
| +#define FIT_ALGO_PROP		"algo"
 | |
| +#define FIT_VALUE_PROP		"value"
 | |
| +#define FIT_IGNORE_PROP		"uboot-ignore"
 | |
| +#define FIT_SIG_NODENAME	"signature"
 | |
| +#define FIT_KEY_REQUIRED	"required"
 | |
| +#define FIT_KEY_HINT		"key-name-hint"
 | |
| +
 | |
| +/* cipher node */
 | |
| +#define FIT_CIPHER_NODENAME	"cipher"
 | |
| +#define FIT_ALGO_PROP		"algo"
 | |
| +
 | |
| +/* image node */
 | |
| +#define FIT_DATA_PROP		"data"
 | |
| +#define FIT_DATA_POSITION_PROP	"data-position"
 | |
| +#define FIT_DATA_OFFSET_PROP	"data-offset"
 | |
| +#define FIT_DATA_SIZE_PROP	"data-size"
 | |
| +#define FIT_TIMESTAMP_PROP	"timestamp"
 | |
| +#define FIT_DESC_PROP		"description"
 | |
| +#define FIT_ARCH_PROP		"arch"
 | |
| +#define FIT_TYPE_PROP		"type"
 | |
| +#define FIT_OS_PROP		"os"
 | |
| +#define FIT_COMP_PROP		"compression"
 | |
| +#define FIT_ENTRY_PROP		"entry"
 | |
| +#define FIT_LOAD_PROP		"load"
 | |
| +
 | |
| +/* configuration node */
 | |
| +#define FIT_KERNEL_PROP		"kernel"
 | |
| +#define FIT_FILESYSTEM_PROP	"filesystem"
 | |
| +#define FIT_RAMDISK_PROP	"ramdisk"
 | |
| +#define FIT_FDT_PROP		"fdt"
 | |
| +#define FIT_LOADABLE_PROP	"loadables"
 | |
| +#define FIT_DEFAULT_PROP	"default"
 | |
| +#define FIT_SETUP_PROP		"setup"
 | |
| +#define FIT_FPGA_PROP		"fpga"
 | |
| +#define FIT_FIRMWARE_PROP	"firmware"
 | |
| +#define FIT_STANDALONE_PROP	"standalone"
 | |
| +
 | |
| +#define FIT_MAX_HASH_LEN	HASH_MAX_DIGEST_SIZE
 | |
| +
 | |
| +#define MIN_FREE_SECT		16
 | |
| +#define REMAIN_VOLNAME		"rootfs_data"
 | |
| +
 | |
| +int parse_fit_partitions(struct parsed_partitions *state, u64 fit_start_sector, u64 sectors, int *slot, int add_remain)
 | |
| +{
 | |
| +	struct address_space *mapping = state->bdev->bd_inode->i_mapping;
 | |
| +	struct page *page;
 | |
| +	void *fit, *init_fit;
 | |
| +	struct partition_meta_info *info;
 | |
| +	char tmp[sizeof(info->volname)];
 | |
| +	u64 dsize, dsectors, imgmaxsect = 0;
 | |
| +	u32 size, image_pos, image_len;
 | |
| +	const u32 *image_offset_be, *image_len_be, *image_pos_be;
 | |
| +	int ret = 1, node, images, config;
 | |
| +	const char *image_name, *image_type, *image_description, *config_default,
 | |
| +		*config_description, *config_loadables;
 | |
| +	int image_name_len, image_type_len, image_description_len, config_default_len,
 | |
| +		config_description_len, config_loadables_len;
 | |
| +	sector_t start_sect, nr_sects;
 | |
| +	size_t label_min;
 | |
| +
 | |
| +	if (fit_start_sector % (1<<(PAGE_SHIFT - SECTOR_SHIFT)))
 | |
| +		return -ERANGE;
 | |
| +
 | |
| +	page = read_mapping_page(mapping, fit_start_sector >> (PAGE_SHIFT - SECTOR_SHIFT), NULL);
 | |
| +	if (!page)
 | |
| +		return -ENOMEM;
 | |
| +
 | |
| +	init_fit = page_address(page);
 | |
| +
 | |
| +	if (!init_fit) {
 | |
| +		put_page(page);
 | |
| +		return -EFAULT;
 | |
| +	}
 | |
| +
 | |
| +	if (fdt_check_header(init_fit)) {
 | |
| +		put_page(page);
 | |
| +		return 0;
 | |
| +	}
 | |
| +
 | |
| +	dsectors = get_capacity(state->bdev->bd_disk);
 | |
| +	if (sectors)
 | |
| +		dsectors = (dsectors>sectors)?sectors:dsectors;
 | |
| +
 | |
| +	dsize = dsectors << SECTOR_SHIFT;
 | |
| +	printk(KERN_DEBUG "FIT: volume size: %llu sectors (%llu bytes)\n", dsectors, dsize);
 | |
| +
 | |
| +	size = fdt_totalsize(init_fit);
 | |
| +	printk(KERN_DEBUG "FIT: FDT structure size: %u bytes\n", size);
 | |
| +	if (size > PAGE_SIZE) {
 | |
| +		printk(KERN_ERR "FIT: FDT structure beyond page boundaries, use 'mkimage -E ...'!\n");
 | |
| +		put_page(page);
 | |
| +		return -ENOTSUPP;
 | |
| +	}
 | |
| +
 | |
| +	if (size >= dsize) {
 | |
| +		put_page(page);
 | |
| +		state->access_beyond_eod = (size >= dsize);
 | |
| +		return 0;
 | |
| +	}
 | |
| +
 | |
| +	fit = kmemdup(init_fit, size, GFP_KERNEL);
 | |
| +	put_page(page);
 | |
| +	if (!fit)
 | |
| +		return -ENOMEM;
 | |
| +
 | |
| +	config = fdt_path_offset(fit, FIT_CONFS_PATH);
 | |
| +	if (config < 0) {
 | |
| +		printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_CONFS_PATH, images);
 | |
| +		ret = -ENOENT;
 | |
| +		goto ret_out;
 | |
| +	}
 | |
| +
 | |
| +	config_default = fdt_getprop(fit, config, FIT_DEFAULT_PROP, &config_default_len);
 | |
| +
 | |
| +	if (!config_default) {
 | |
| +		printk(KERN_ERR "FIT: Cannot find default configuration\n");
 | |
| +		ret = -ENOENT;
 | |
| +		goto ret_out;
 | |
| +	}
 | |
| +
 | |
| +	node = fdt_subnode_offset(fit, config, config_default);
 | |
| +	if (node < 0) {
 | |
| +		printk(KERN_ERR "FIT: Cannot find %s node: %d\n", config_default, node);
 | |
| +		ret = -ENOENT;
 | |
| +		goto ret_out;
 | |
| +	}
 | |
| +
 | |
| +	config_description = fdt_getprop(fit, node, FIT_DESC_PROP, &config_description_len);
 | |
| +	config_loadables = fdt_getprop(fit, node, FIT_LOADABLE_PROP, &config_loadables_len);
 | |
| +
 | |
| +	printk(KERN_DEBUG "FIT: Default configuration: %s%s%s%s\n", config_default,
 | |
| +		config_description?" (":"", config_description?:"", config_description?")":"");
 | |
| +
 | |
| +	images = fdt_path_offset(fit, FIT_IMAGES_PATH);
 | |
| +	if (images < 0) {
 | |
| +		printk(KERN_ERR "FIT: Cannot find %s node: %d\n", FIT_IMAGES_PATH, images);
 | |
| +		ret = -EINVAL;
 | |
| +		goto ret_out;
 | |
| +	}
 | |
| +
 | |
| +	fdt_for_each_subnode(node, fit, images) {
 | |
| +		image_name = fdt_get_name(fit, node, &image_name_len);
 | |
| +		image_type = fdt_getprop(fit, node, FIT_TYPE_PROP, &image_type_len);
 | |
| +		image_offset_be = fdt_getprop(fit, node, FIT_DATA_OFFSET_PROP, NULL);
 | |
| +		image_pos_be = fdt_getprop(fit, node, FIT_DATA_POSITION_PROP, NULL);
 | |
| +		image_len_be = fdt_getprop(fit, node, FIT_DATA_SIZE_PROP, NULL);
 | |
| +		if (!image_name || !image_type || !image_len_be)
 | |
| +			continue;
 | |
| +
 | |
| +		image_len = be32_to_cpu(*image_len_be);
 | |
| +		if (!image_len)
 | |
| +			continue;
 | |
| +
 | |
| +		if (image_offset_be)
 | |
| +			image_pos = be32_to_cpu(*image_offset_be) + size;
 | |
| +		else if (image_pos_be)
 | |
| +			image_pos = be32_to_cpu(*image_pos_be);
 | |
| +		else
 | |
| +			continue;
 | |
| +
 | |
| +		image_description = fdt_getprop(fit, node, FIT_DESC_PROP, &image_description_len);
 | |
| +
 | |
| +		printk(KERN_DEBUG "FIT: %16s sub-image 0x%08x - 0x%08x '%s' %s%s%s\n",
 | |
| +			image_type, image_pos, image_pos + image_len, image_name,
 | |
| +			image_description?"(":"", image_description?:"", image_description?") ":"");
 | |
| +
 | |
| +		if (strcmp(image_type, FIT_FILESYSTEM_PROP))
 | |
| +			continue;
 | |
| +
 | |
| +		if (image_pos & ((1 << PAGE_SHIFT)-1)) {
 | |
| +			printk(KERN_ERR "FIT: image %s start not aligned to page boundaries, skipping\n", image_name);
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		if (image_len & ((1 << PAGE_SHIFT)-1)) {
 | |
| +			printk(KERN_ERR "FIT: sub-image %s end not aligned to page boundaries, skipping\n", image_name);
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		start_sect = image_pos >> SECTOR_SHIFT;
 | |
| +		nr_sects = image_len >> SECTOR_SHIFT;
 | |
| +		imgmaxsect = (imgmaxsect < (start_sect + nr_sects))?(start_sect + nr_sects):imgmaxsect;
 | |
| +
 | |
| +		if (start_sect + nr_sects > dsectors) {
 | |
| +			state->access_beyond_eod = 1;
 | |
| +			continue;
 | |
| +		}
 | |
| +
 | |
| +		put_partition(state, ++(*slot), fit_start_sector + start_sect, nr_sects);
 | |
| +		state->parts[*slot].flags = 0;
 | |
| +		info = &state->parts[*slot].info;
 | |
| +
 | |
| +		label_min = min_t(int, sizeof(info->volname) - 1, image_name_len);
 | |
| +		strncpy(info->volname, image_name, label_min);
 | |
| +		info->volname[label_min] = '\0';
 | |
| +
 | |
| +		snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
 | |
| +		strlcat(state->pp_buf, tmp, PAGE_SIZE);
 | |
| +
 | |
| +		state->parts[*slot].has_info = true;
 | |
| +
 | |
| +		if (config_loadables && !strcmp(image_name, config_loadables)) {
 | |
| +			printk(KERN_DEBUG "FIT: selecting configured loadable %s to be root filesystem\n", image_name);
 | |
| +			state->parts[*slot].flags |= ADDPART_FLAG_ROOTDEV;
 | |
| +		}
 | |
| +	}
 | |
| +
 | |
| +	if (add_remain && (imgmaxsect + MIN_FREE_SECT) < dsectors) {
 | |
| +		put_partition(state, ++(*slot), fit_start_sector + imgmaxsect, dsectors - imgmaxsect);
 | |
| +		state->parts[*slot].flags = 0;
 | |
| +		info = &state->parts[*slot].info;
 | |
| +		strcpy(info->volname, REMAIN_VOLNAME);
 | |
| +		snprintf(tmp, sizeof(tmp), "(%s)", REMAIN_VOLNAME);
 | |
| +		strlcat(state->pp_buf, tmp, PAGE_SIZE);
 | |
| +	}
 | |
| +ret_out:
 | |
| +	kfree(fit);
 | |
| +	return ret;
 | |
| +}
 | |
| +
 | |
| +int fit_partition(struct parsed_partitions *state) {
 | |
| +	int slot = 0;
 | |
| +	return parse_fit_partitions(state, 0, 0, &slot, 0);
 | |
| +}
 | |
| diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig
 | |
| index 4832b8d9e4..794a39f2c3 100644
 | |
| --- a/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig
 | |
| +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Kconfig
 | |
| @@ -20,6 +20,11 @@ config MTD_SPLIT_SQUASHFS_ROOT
 | |
|  
 | |
|  comment "Firmware partition parsers"
 | |
|  
 | |
| +config MTD_SPLIT_BCM63XX_FW
 | |
| +	bool "BCM63xx firmware parser"
 | |
| +	depends on MTD_SPLIT_SUPPORT
 | |
| +	select MTD_SPLIT
 | |
| +
 | |
|  config MTD_SPLIT_BCM_WFI_FW
 | |
|  	bool "Broadcom Whole Flash Image parser"
 | |
|  	depends on MTD_SPLIT_SUPPORT
 | |
| diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile
 | |
| index 9217d8f64f..1461099b7c 100644
 | |
| --- a/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile
 | |
| +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/Makefile
 | |
| @@ -1,4 +1,5 @@
 | |
|  obj-$(CONFIG_MTD_SPLIT)		+= mtdsplit.o
 | |
| +obj-$(CONFIG_MTD_SPLIT_BCM63XX_FW) += mtdsplit_bcm63xx.o
 | |
|  obj-$(CONFIG_MTD_SPLIT_BCM_WFI_FW) += mtdsplit_bcm_wfi.o
 | |
|  obj-$(CONFIG_MTD_SPLIT_CFE_BOOTFS) += mtdsplit_cfe_bootfs.o
 | |
|  obj-$(CONFIG_MTD_SPLIT_SEAMA_FW) += mtdsplit_seama.o
 | |
| diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c
 | |
| new file mode 100644
 | |
| index 0000000000..3a4b8a754f
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_bcm63xx.c
 | |
| @@ -0,0 +1,186 @@
 | |
| +/*
 | |
| + * Firmware MTD split for BCM63XX, based on bcm63xxpart.c
 | |
| + *
 | |
| + * Copyright (C) 2006-2008 Florian Fainelli <florian@openwrt.org>
 | |
| + * Copyright (C) 2006-2008 Mike Albon <malbon@openwrt.org>
 | |
| + * Copyright (C) 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net>
 | |
| + * Copyright (C) 2011-2013 Jonas Gorski <jonas.gorski@gmail.com>
 | |
| + * Copyright (C) 2015 Simon Arlott <simon@fire.lp0.eu>
 | |
| + * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
 | |
| + *
 | |
| + * This program is free software; you can redistribute it and/or modify it
 | |
| + * under the terms of the GNU General Public License version 2 as published
 | |
| + * by the Free Software Foundation.
 | |
| + *
 | |
| + */
 | |
| +
 | |
| +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 | |
| +
 | |
| +#include <linux/bcm963xx_tag.h>
 | |
| +#include <linux/crc32.h>
 | |
| +#include <linux/init.h>
 | |
| +#include <linux/kernel.h>
 | |
| +#include <linux/module.h>
 | |
| +#include <linux/slab.h>
 | |
| +#include <linux/byteorder/generic.h>
 | |
| +#include <linux/mtd/mtd.h>
 | |
| +#include <linux/mtd/partitions.h>
 | |
| +
 | |
| +#include "mtdsplit.h"
 | |
| +
 | |
| +/* Ensure strings read from flash structs are null terminated */
 | |
| +#define STR_NULL_TERMINATE(x) \
 | |
| +	do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0)
 | |
| +
 | |
| +#define BCM63XX_NR_PARTS 2
 | |
| +
 | |
| +static int bcm63xx_read_image_tag(struct mtd_info *master, loff_t offset,
 | |
| +				  struct bcm_tag *hdr)
 | |
| +{
 | |
| +	int ret;
 | |
| +	size_t retlen;
 | |
| +	u32 computed_crc;
 | |
| +
 | |
| +	ret = mtd_read(master, offset, sizeof(*hdr), &retlen, (void *) hdr);
 | |
| +	if (ret)
 | |
| +		return ret;
 | |
| +
 | |
| +	if (retlen != sizeof(*hdr))
 | |
| +		return -EIO;
 | |
| +
 | |
| +	computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)hdr,
 | |
| +				offsetof(struct bcm_tag, header_crc));
 | |
| +	if (computed_crc == hdr->header_crc) {
 | |
| +	    STR_NULL_TERMINATE(hdr->board_id);
 | |
| +	    STR_NULL_TERMINATE(hdr->tag_version);
 | |
| +
 | |
| +		pr_info("CFE image tag found at 0x%llx with version %s, "
 | |
| +			"board type %s\n", offset, hdr->tag_version,
 | |
| +			hdr->board_id);
 | |
| +
 | |
| +		return 0;
 | |
| +	} else {
 | |
| +		pr_err("CFE image tag at 0x%llx CRC invalid "
 | |
| +		       "(expected %08x, actual %08x)\n",
 | |
| +		       offset, hdr->header_crc, computed_crc);
 | |
| +
 | |
| +		return 1;
 | |
| +	}
 | |
| +}
 | |
| +
 | |
| +static int bcm63xx_parse_partitions(struct mtd_info *master,
 | |
| +				    const struct mtd_partition **pparts,
 | |
| +				    struct bcm_tag *hdr)
 | |
| +{
 | |
| +	struct mtd_partition *parts;
 | |
| +	unsigned int flash_image_start;
 | |
| +	unsigned int kernel_address;
 | |
| +	unsigned int kernel_length;
 | |
| +	size_t kernel_offset = 0, kernel_size = 0;
 | |
| +	size_t rootfs_offset = 0, rootfs_size = 0;
 | |
| +	int kernel_part, rootfs_part;
 | |
| +
 | |
| +	STR_NULL_TERMINATE(hdr->flash_image_start);
 | |
| +	if (kstrtouint(hdr->flash_image_start, 10, &flash_image_start) ||
 | |
| +	    flash_image_start < BCM963XX_EXTENDED_SIZE) {
 | |
| +		pr_err("invalid rootfs address: %*ph\n",
 | |
| +		       (int) sizeof(hdr->flash_image_start),
 | |
| +		       hdr->flash_image_start);
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
| +
 | |
| +	STR_NULL_TERMINATE(hdr->kernel_address);
 | |
| +	if (kstrtouint(hdr->kernel_address, 10, &kernel_address) ||
 | |
| +	    kernel_address < BCM963XX_EXTENDED_SIZE) {
 | |
| +		pr_err("invalid kernel address: %*ph\n",
 | |
| +		       (int) sizeof(hdr->kernel_address), hdr->kernel_address);
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
| +
 | |
| +	STR_NULL_TERMINATE(hdr->kernel_length);
 | |
| +	if (kstrtouint(hdr->kernel_length, 10, &kernel_length) ||
 | |
| +	    !kernel_length) {
 | |
| +		pr_err("invalid kernel length: %*ph\n",
 | |
| +		       (int) sizeof(hdr->kernel_length), hdr->kernel_length);
 | |
| +		return -EINVAL;
 | |
| +	}
 | |
| +
 | |
| +	kernel_offset = kernel_address - BCM963XX_EXTENDED_SIZE -
 | |
| +			mtdpart_get_offset(master);
 | |
| +	kernel_size = kernel_length;
 | |
| +
 | |
| +	if (flash_image_start < kernel_address) {
 | |
| +		/* rootfs first */
 | |
| +		rootfs_part = 0;
 | |
| +		kernel_part = 1;
 | |
| +		rootfs_offset = flash_image_start - BCM963XX_EXTENDED_SIZE -
 | |
| +				mtdpart_get_offset(master);
 | |
| +		rootfs_size = kernel_offset - rootfs_offset;
 | |
| +	} else {
 | |
| +		/* kernel first */
 | |
| +		kernel_part = 0;
 | |
| +		rootfs_part = 1;
 | |
| +		rootfs_offset = kernel_offset + kernel_size;
 | |
| +		rootfs_size = master->size - rootfs_offset;
 | |
| +	}
 | |
| +
 | |
| +	if (mtd_check_rootfs_magic(master, rootfs_offset, NULL))
 | |
| +		pr_warn("rootfs magic not found\n");
 | |
| +
 | |
| +	parts = kzalloc(BCM63XX_NR_PARTS * sizeof(*parts), GFP_KERNEL);
 | |
| +	if (!parts)
 | |
| +		return -ENOMEM;
 | |
| +
 | |
| +	parts[kernel_part].name = KERNEL_PART_NAME;
 | |
| +	parts[kernel_part].offset = kernel_offset;
 | |
| +	parts[kernel_part].size = kernel_size;
 | |
| +
 | |
| +	parts[rootfs_part].name = ROOTFS_PART_NAME;
 | |
| +	parts[rootfs_part].offset = rootfs_offset;
 | |
| +	parts[rootfs_part].size = rootfs_size;
 | |
| +
 | |
| +	*pparts = parts;
 | |
| +	return BCM63XX_NR_PARTS;
 | |
| +}
 | |
| +
 | |
| +static int mtdsplit_parse_bcm63xx(struct mtd_info *master,
 | |
| +				  const struct mtd_partition **pparts,
 | |
| +				  struct mtd_part_parser_data *data)
 | |
| +{
 | |
| +	struct bcm_tag hdr;
 | |
| +	loff_t offset;
 | |
| +
 | |
| +	if (mtd_type_is_nand(master))
 | |
| +		return -EINVAL;
 | |
| +
 | |
| +	/* find bcm63xx_cfe image on erase block boundaries */
 | |
| +	for (offset = 0; offset < master->size; offset += master->erasesize) {
 | |
| +		if (!bcm63xx_read_image_tag(master, offset, (void *) &hdr))
 | |
| +			return bcm63xx_parse_partitions(master, pparts,
 | |
| +							(void *) &hdr);
 | |
| +	}
 | |
| +
 | |
| +	return -EINVAL;
 | |
| +}
 | |
| +
 | |
| +static const struct of_device_id mtdsplit_fit_of_match_table[] = {
 | |
| +	{ .compatible = "brcm,bcm963xx-imagetag" },
 | |
| +	{ },
 | |
| +};
 | |
| +
 | |
| +static struct mtd_part_parser mtdsplit_bcm63xx_parser = {
 | |
| +	.owner = THIS_MODULE,
 | |
| +	.name = "bcm63xx-fw",
 | |
| +	.of_match_table = mtdsplit_fit_of_match_table,
 | |
| +	.parse_fn = mtdsplit_parse_bcm63xx,
 | |
| +	.type = MTD_PARSER_TYPE_FIRMWARE,
 | |
| +};
 | |
| +
 | |
| +static int __init mtdsplit_bcm63xx_init(void)
 | |
| +{
 | |
| +	register_mtd_parser(&mtdsplit_bcm63xx_parser);
 | |
| +
 | |
| +	return 0;
 | |
| +}
 | |
| +
 | |
| +module_init(mtdsplit_bcm63xx_init);
 | |
| diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
 | |
| index 67ee33d085..5cc1658dbd 100644
 | |
| --- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
 | |
| +++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
 | |
| @@ -49,6 +49,8 @@ mtdsplit_fit_parse(struct mtd_info *mtd,
 | |
|  		   const struct mtd_partition **pparts,
 | |
|  	           struct mtd_part_parser_data *data)
 | |
|  {
 | |
| +	struct device_node *np = mtd_get_of_node(mtd);
 | |
| +	const char *cmdline_match = NULL;
 | |
|  	struct fdt_header hdr;
 | |
|  	size_t hdr_len, retlen;
 | |
|  	size_t offset;
 | |
| @@ -57,6 +59,10 @@ mtdsplit_fit_parse(struct mtd_info *mtd,
 | |
|  	struct mtd_partition *parts;
 | |
|  	int ret;
 | |
|  
 | |
| +	of_property_read_string(np, "openwrt,cmdline-match", &cmdline_match);
 | |
| +	if (cmdline_match && !strstr(saved_command_line, cmdline_match))
 | |
| +		return -ENODEV;
 | |
| +
 | |
|  	hdr_len = sizeof(struct fdt_header);
 | |
|  
 | |
|  	/* Parse the MTD device & search for the FIT image location */
 | |
| diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
 | |
| index 0b0348bfdf..ef0fc54949 100644
 | |
| --- a/target/linux/generic/files/drivers/net/phy/ar8216.c
 | |
| +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
 | |
| @@ -513,6 +513,8 @@ ar8216_read_port_link(struct ar8xxx_priv *priv, int port,
 | |
|  	}
 | |
|  }
 | |
|  
 | |
| +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
 | |
| +
 | |
|  static struct sk_buff *
 | |
|  ar8216_mangle_tx(struct net_device *dev, struct sk_buff *skb)
 | |
|  {
 | |
| @@ -579,6 +581,8 @@ ar8216_mangle_rx(struct net_device *dev, struct sk_buff *skb)
 | |
|  	buf[15 + 2] = vlan & 0xff;
 | |
|  }
 | |
|  
 | |
| +#endif
 | |
| +
 | |
|  int
 | |
|  ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val)
 | |
|  {
 | |
| @@ -887,7 +891,11 @@ ar8216_phy_write(struct ar8xxx_priv *priv, int addr, int regnum, u16 val)
 | |
|  static int
 | |
|  ar8229_hw_init(struct ar8xxx_priv *priv)
 | |
|  {
 | |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
 | |
| +	phy_interface_t phy_if_mode;
 | |
| +#else
 | |
|  	int phy_if_mode;
 | |
| +#endif
 | |
|  
 | |
|  	if (priv->initialized)
 | |
|  		return 0;
 | |
| @@ -895,7 +903,11 @@ ar8229_hw_init(struct ar8xxx_priv *priv)
 | |
|  	ar8xxx_write(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET);
 | |
|  	ar8xxx_reg_wait(priv, AR8216_REG_CTRL, AR8216_CTRL_RESET, 0, 1000);
 | |
|  
 | |
| +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
 | |
| +	of_get_phy_mode(priv->pdev->of_node, &phy_if_mode);
 | |
| +#else
 | |
|  	phy_if_mode = of_get_phy_mode(priv->pdev->of_node);
 | |
| +#endif
 | |
|  
 | |
|  	if (phy_if_mode == PHY_INTERFACE_MODE_GMII) {
 | |
|  		ar8xxx_write(priv, AR8229_REG_OPER_MODE0,
 | |
| @@ -2449,6 +2461,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev)
 | |
|  	if (ret)
 | |
|  		return ret;
 | |
|  
 | |
| +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
 | |
|  	/* VID fixup only needed on ar8216 */
 | |
|  	if (chip_is_ar8216(priv)) {
 | |
|  		dev->phy_ptr = priv;
 | |
| @@ -2456,6 +2469,7 @@ ar8xxx_phy_config_init(struct phy_device *phydev)
 | |
|  		dev->eth_mangle_rx = ar8216_mangle_rx;
 | |
|  		dev->eth_mangle_tx = ar8216_mangle_tx;
 | |
|  	}
 | |
| +#endif
 | |
|  
 | |
|  	return 0;
 | |
|  }
 | |
| @@ -2687,10 +2701,12 @@ ar8xxx_phy_detach(struct phy_device *phydev)
 | |
|  	if (!dev)
 | |
|  		return;
 | |
|  
 | |
| +#ifdef CONFIG_ETHERNET_PACKET_MANGLE
 | |
|  	dev->phy_ptr = NULL;
 | |
|  	dev->priv_flags &= ~IFF_NO_IP_ALIGN;
 | |
|  	dev->eth_mangle_rx = NULL;
 | |
|  	dev->eth_mangle_tx = NULL;
 | |
| +#endif
 | |
|  }
 | |
|  
 | |
|  static void
 | |
| diff --git a/target/linux/generic/hack-5.10/204-module_strip.patch b/target/linux/generic/hack-5.10/204-module_strip.patch
 | |
| new file mode 100644
 | |
| index 0000000000..06159b0120
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/204-module_strip.patch
 | |
| @@ -0,0 +1,196 @@
 | |
| +From a779a482fb9b9f8fcdf8b2519c789b4b9bb5dd05 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 16:56:48 +0200
 | |
| +Subject: build: add a hack for removing non-essential module info
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/linux/module.h      | 13 ++++++++-----
 | |
| + include/linux/moduleparam.h | 15 ++++++++++++---
 | |
| + init/Kconfig                |  7 +++++++
 | |
| + kernel/module.c             |  5 ++++-
 | |
| + scripts/mod/modpost.c       | 12 ++++++++++++
 | |
| + 5 files changed, 43 insertions(+), 9 deletions(-)
 | |
| +
 | |
| +--- a/include/linux/module.h
 | |
| ++++ b/include/linux/module.h
 | |
| +@@ -161,6 +161,7 @@ extern void cleanup_module(void);
 | |
| + 
 | |
| + /* Generic info of form tag = "info" */
 | |
| + #define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
 | |
| ++#define MODULE_INFO_STRIP(tag, info) __MODULE_INFO_STRIP(tag, tag, info)
 | |
| + 
 | |
| + /* For userspace: you can also call me... */
 | |
| + #define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
 | |
| +@@ -230,12 +231,12 @@ extern void cleanup_module(void);
 | |
| +  * Author(s), use "Name <email>" or just "Name", for multiple
 | |
| +  * authors use multiple MODULE_AUTHOR() statements/lines.
 | |
| +  */
 | |
| +-#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
 | |
| ++#define MODULE_AUTHOR(_author) MODULE_INFO_STRIP(author, _author)
 | |
| + 
 | |
| + /* What your module does. */
 | |
| +-#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
 | |
| ++#define MODULE_DESCRIPTION(_description) MODULE_INFO_STRIP(description, _description)
 | |
| + 
 | |
| +-#ifdef MODULE
 | |
| ++#if defined(MODULE) && !defined(CONFIG_MODULE_STRIPPED)
 | |
| + /* Creates an alias so file2alias.c can find device table. */
 | |
| + #define MODULE_DEVICE_TABLE(type, name)					\
 | |
| + extern typeof(name) __mod_##type##__##name##_device_table		\
 | |
| +@@ -262,7 +263,9 @@ extern typeof(name) __mod_##type##__##na
 | |
| +  */
 | |
| + 
 | |
| + #if defined(MODULE) || !defined(CONFIG_SYSFS)
 | |
| +-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
 | |
| ++#define MODULE_VERSION(_version) MODULE_INFO_STRIP(version, _version)
 | |
| ++#elif defined(CONFIG_MODULE_STRIPPED)
 | |
| ++#define MODULE_VERSION(_version) __MODULE_INFO_DISABLED(version)
 | |
| + #else
 | |
| + #define MODULE_VERSION(_version)					\
 | |
| + 	MODULE_INFO(version, _version);					\
 | |
| +@@ -285,7 +288,7 @@ extern typeof(name) __mod_##type##__##na
 | |
| + /* Optional firmware file (or files) needed by the module
 | |
| +  * format is simply firmware file name.  Multiple firmware
 | |
| +  * files require multiple MODULE_FIRMWARE() specifiers */
 | |
| +-#define MODULE_FIRMWARE(_firmware) MODULE_INFO(firmware, _firmware)
 | |
| ++#define MODULE_FIRMWARE(_firmware) MODULE_INFO_STRIP(firmware, _firmware)
 | |
| + 
 | |
| + #define MODULE_IMPORT_NS(ns) MODULE_INFO(import_ns, #ns)
 | |
| + 
 | |
| +--- a/include/linux/moduleparam.h
 | |
| ++++ b/include/linux/moduleparam.h
 | |
| +@@ -20,6 +20,16 @@
 | |
| + /* Chosen so that structs with an unsigned long line up. */
 | |
| + #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
 | |
| + 
 | |
| ++/* This struct is here for syntactic coherency, it is not used */
 | |
| ++#define __MODULE_INFO_DISABLED(name)					  \
 | |
| ++  struct __UNIQUE_ID(name) {}
 | |
| ++
 | |
| ++#ifdef CONFIG_MODULE_STRIPPED
 | |
| ++#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO_DISABLED(name)
 | |
| ++#else
 | |
| ++#define __MODULE_INFO_STRIP(tag, name, info) __MODULE_INFO(tag, name, info)
 | |
| ++#endif
 | |
| ++
 | |
| + #define __MODULE_INFO(tag, name, info)					  \
 | |
| + static const char __UNIQUE_ID(name)[]					  \
 | |
| +   __used __section(".modinfo") __attribute__((unused, aligned(1)))	  \
 | |
| +@@ -31,7 +41,7 @@ static const char __UNIQUE_ID(name)[]
 | |
| + /* One for each parameter, describing how to use it.  Some files do
 | |
| +    multiple of these per line, so can't just use MODULE_INFO. */
 | |
| + #define MODULE_PARM_DESC(_parm, desc) \
 | |
| +-	__MODULE_INFO(parm, _parm, #_parm ":" desc)
 | |
| ++	__MODULE_INFO_STRIP(parm, _parm, #_parm ":" desc)
 | |
| + 
 | |
| + struct kernel_param;
 | |
| + 
 | |
| +--- a/init/Kconfig
 | |
| ++++ b/init/Kconfig
 | |
| +@@ -2338,6 +2338,13 @@ config UNUSED_KSYMS_WHITELIST
 | |
| + 	  one per line. The path can be absolute, or relative to the kernel
 | |
| + 	  source tree.
 | |
| + 
 | |
| ++config MODULE_STRIPPED
 | |
| ++	bool "Reduce module size"
 | |
| ++	depends on MODULES
 | |
| ++	help
 | |
| ++	  Remove module parameter descriptions, author info, version, aliases,
 | |
| ++	  device tables, etc.
 | |
| ++
 | |
| + endif # MODULES
 | |
| + 
 | |
| + config MODULES_TREE_LOOKUP
 | |
| +--- a/kernel/module.c
 | |
| ++++ b/kernel/module.c
 | |
| +@@ -3243,9 +3243,11 @@ static int setup_load_info(struct load_i
 | |
| + 
 | |
| + static int check_modinfo(struct module *mod, struct load_info *info, int flags)
 | |
| + {
 | |
| +-	const char *modmagic = get_modinfo(info, "vermagic");
 | |
| + 	int err;
 | |
| + 
 | |
| ++#ifndef CONFIG_MODULE_STRIPPED
 | |
| ++	const char *modmagic = get_modinfo(info, "vermagic");
 | |
| ++
 | |
| + 	if (flags & MODULE_INIT_IGNORE_VERMAGIC)
 | |
| + 		modmagic = NULL;
 | |
| + 
 | |
| +@@ -3266,6 +3268,7 @@ static int check_modinfo(struct module *
 | |
| + 				mod->name);
 | |
| + 		add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
 | |
| + 	}
 | |
| ++#endif
 | |
| + 
 | |
| + 	check_modinfo_retpoline(mod, info);
 | |
| + 
 | |
| +--- a/scripts/mod/modpost.c
 | |
| ++++ b/scripts/mod/modpost.c
 | |
| +@@ -2037,7 +2037,9 @@ static void read_symbols(const char *mod
 | |
| + 		symname = remove_dot(info.strtab + sym->st_name);
 | |
| + 
 | |
| + 		handle_symbol(mod, &info, sym, symname);
 | |
| ++#ifndef CONFIG_MODULE_STRIPPED
 | |
| + 		handle_moddevtable(mod, &info, sym, symname);
 | |
| ++#endif
 | |
| + 	}
 | |
| + 
 | |
| + 	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
 | |
| +@@ -2250,8 +2252,10 @@ static void add_header(struct buffer *b,
 | |
| + 	buf_printf(b, "\n");
 | |
| + 	buf_printf(b, "BUILD_SALT;\n");
 | |
| + 	buf_printf(b, "\n");
 | |
| ++#ifndef CONFIG_MODULE_STRIPPED
 | |
| + 	buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
 | |
| + 	buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
 | |
| ++#endif
 | |
| + 	buf_printf(b, "\n");
 | |
| + 	buf_printf(b, "__visible struct module __this_module\n");
 | |
| + 	buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
 | |
| +@@ -2268,8 +2272,10 @@ static void add_header(struct buffer *b,
 | |
| + 
 | |
| + static void add_intree_flag(struct buffer *b, int is_intree)
 | |
| + {
 | |
| ++#ifndef CONFIG_MODULE_STRIPPED
 | |
| + 	if (is_intree)
 | |
| + 		buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");
 | |
| ++#endif
 | |
| + }
 | |
| + 
 | |
| + /* Cannot check for assembler */
 | |
| +@@ -2282,8 +2288,10 @@ static void add_retpoline(struct buffer
 | |
| + 
 | |
| + static void add_staging_flag(struct buffer *b, const char *name)
 | |
| + {
 | |
| ++#ifndef CONFIG_MODULE_STRIPPED
 | |
| + 	if (strstarts(name, "drivers/staging"))
 | |
| + 		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
 | |
| ++#endif
 | |
| + }
 | |
| + 
 | |
| + /**
 | |
| +@@ -2367,11 +2375,13 @@ static void add_depends(struct buffer *b
 | |
| + 
 | |
| + static void add_srcversion(struct buffer *b, struct module *mod)
 | |
| + {
 | |
| ++#ifndef CONFIG_MODULE_STRIPPED
 | |
| + 	if (mod->srcversion[0]) {
 | |
| + 		buf_printf(b, "\n");
 | |
| + 		buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
 | |
| + 			   mod->srcversion);
 | |
| + 	}
 | |
| ++#endif
 | |
| + }
 | |
| + 
 | |
| + static void write_buf(struct buffer *b, const char *fname)
 | |
| +@@ -2643,7 +2653,9 @@ int main(int argc, char **argv)
 | |
| + 		add_staging_flag(&buf, mod->name);
 | |
| + 		err |= add_versions(&buf, mod);
 | |
| + 		add_depends(&buf, mod);
 | |
| ++#ifndef CONFIG_MODULE_STRIPPED
 | |
| + 		add_moddevtable(&buf, mod);
 | |
| ++#endif
 | |
| + 		add_srcversion(&buf, mod);
 | |
| + 
 | |
| + 		sprintf(fname, "%s.mod.c", mod->name);
 | |
| diff --git a/target/linux/generic/hack-5.10/210-darwin_scripts_include.patch b/target/linux/generic/hack-5.10/210-darwin_scripts_include.patch
 | |
| new file mode 100644
 | |
| index 0000000000..be6adc0d11
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/210-darwin_scripts_include.patch
 | |
| @@ -0,0 +1,3053 @@
 | |
| +From db7c30dcd9a0391bf13b62c9f91e144d762ef43a Mon Sep 17 00:00:00 2001
 | |
| +From: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Date: Fri, 7 Jul 2017 17:00:49 +0200
 | |
| +Subject: Add an OSX specific patch to make the kernel be compiled
 | |
| +
 | |
| +lede-commit: 3fc2a24f0422b2f55f9ed43f116db3111f700526
 | |
| +Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +---
 | |
| + scripts/kconfig/Makefile   |    3 +
 | |
| + scripts/mod/elf.h          | 3007 ++++++++++++++++++++++++++++++++++++++++++++
 | |
| + scripts/mod/mk_elfconfig.c |    4 +
 | |
| + scripts/mod/modpost.h      |    4 +
 | |
| + 4 files changed, 3018 insertions(+)
 | |
| + create mode 100644 scripts/mod/elf.h
 | |
| +
 | |
| +--- /dev/null
 | |
| ++++ b/scripts/mod/elf.h
 | |
| +@@ -0,0 +1,3007 @@
 | |
| ++/* This file defines standard ELF types, structures, and macros.
 | |
| ++   Copyright (C) 1995-2012 Free Software Foundation, Inc.
 | |
| ++   This file is part of the GNU C Library.
 | |
| ++
 | |
| ++   The GNU C Library is free software; you can redistribute it and/or
 | |
| ++   modify it under the terms of the GNU Lesser General Public
 | |
| ++   License as published by the Free Software Foundation; either
 | |
| ++   version 2.1 of the License, or (at your option) any later version.
 | |
| ++
 | |
| ++   The GNU C Library 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
 | |
| ++   Lesser General Public License for more details.
 | |
| ++
 | |
| ++   You should have received a copy of the GNU Lesser General Public
 | |
| ++   License along with the GNU C Library; if not, see
 | |
| ++   <http://www.gnu.org/licenses/>.  */
 | |
| ++
 | |
| ++#ifndef _ELF_H
 | |
| ++#define	_ELF_H 1
 | |
| ++
 | |
| ++/* Standard ELF types.  */
 | |
| ++
 | |
| ++#include <stdint.h>
 | |
| ++
 | |
| ++/* Type for a 16-bit quantity.  */
 | |
| ++typedef uint16_t Elf32_Half;
 | |
| ++typedef uint16_t Elf64_Half;
 | |
| ++
 | |
| ++/* Types for signed and unsigned 32-bit quantities.  */
 | |
| ++typedef uint32_t Elf32_Word;
 | |
| ++typedef	int32_t  Elf32_Sword;
 | |
| ++typedef uint32_t Elf64_Word;
 | |
| ++typedef	int32_t  Elf64_Sword;
 | |
| ++
 | |
| ++/* Types for signed and unsigned 64-bit quantities.  */
 | |
| ++typedef uint64_t Elf32_Xword;
 | |
| ++typedef	int64_t  Elf32_Sxword;
 | |
| ++typedef uint64_t Elf64_Xword;
 | |
| ++typedef	int64_t  Elf64_Sxword;
 | |
| ++
 | |
| ++/* Type of addresses.  */
 | |
| ++typedef uint32_t Elf32_Addr;
 | |
| ++typedef uint64_t Elf64_Addr;
 | |
| ++
 | |
| ++/* Type of file offsets.  */
 | |
| ++typedef uint32_t Elf32_Off;
 | |
| ++typedef uint64_t Elf64_Off;
 | |
| ++
 | |
| ++/* Type for section indices, which are 16-bit quantities.  */
 | |
| ++typedef uint16_t Elf32_Section;
 | |
| ++typedef uint16_t Elf64_Section;
 | |
| ++
 | |
| ++/* Type for version symbol information.  */
 | |
| ++typedef Elf32_Half Elf32_Versym;
 | |
| ++typedef Elf64_Half Elf64_Versym;
 | |
| ++
 | |
| ++
 | |
| ++/* The ELF file header.  This appears at the start of every ELF file.  */
 | |
| ++
 | |
| ++#define EI_NIDENT (16)
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
 | |
| ++  Elf32_Half	e_type;			/* Object file type */
 | |
| ++  Elf32_Half	e_machine;		/* Architecture */
 | |
| ++  Elf32_Word	e_version;		/* Object file version */
 | |
| ++  Elf32_Addr	e_entry;		/* Entry point virtual address */
 | |
| ++  Elf32_Off	e_phoff;		/* Program header table file offset */
 | |
| ++  Elf32_Off	e_shoff;		/* Section header table file offset */
 | |
| ++  Elf32_Word	e_flags;		/* Processor-specific flags */
 | |
| ++  Elf32_Half	e_ehsize;		/* ELF header size in bytes */
 | |
| ++  Elf32_Half	e_phentsize;		/* Program header table entry size */
 | |
| ++  Elf32_Half	e_phnum;		/* Program header table entry count */
 | |
| ++  Elf32_Half	e_shentsize;		/* Section header table entry size */
 | |
| ++  Elf32_Half	e_shnum;		/* Section header table entry count */
 | |
| ++  Elf32_Half	e_shstrndx;		/* Section header string table index */
 | |
| ++} Elf32_Ehdr;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  unsigned char	e_ident[EI_NIDENT];	/* Magic number and other info */
 | |
| ++  Elf64_Half	e_type;			/* Object file type */
 | |
| ++  Elf64_Half	e_machine;		/* Architecture */
 | |
| ++  Elf64_Word	e_version;		/* Object file version */
 | |
| ++  Elf64_Addr	e_entry;		/* Entry point virtual address */
 | |
| ++  Elf64_Off	e_phoff;		/* Program header table file offset */
 | |
| ++  Elf64_Off	e_shoff;		/* Section header table file offset */
 | |
| ++  Elf64_Word	e_flags;		/* Processor-specific flags */
 | |
| ++  Elf64_Half	e_ehsize;		/* ELF header size in bytes */
 | |
| ++  Elf64_Half	e_phentsize;		/* Program header table entry size */
 | |
| ++  Elf64_Half	e_phnum;		/* Program header table entry count */
 | |
| ++  Elf64_Half	e_shentsize;		/* Section header table entry size */
 | |
| ++  Elf64_Half	e_shnum;		/* Section header table entry count */
 | |
| ++  Elf64_Half	e_shstrndx;		/* Section header string table index */
 | |
| ++} Elf64_Ehdr;
 | |
| ++
 | |
| ++/* Fields in the e_ident array.  The EI_* macros are indices into the
 | |
| ++   array.  The macros under each EI_* macro are the values the byte
 | |
| ++   may have.  */
 | |
| ++
 | |
| ++#define EI_MAG0		0		/* File identification byte 0 index */
 | |
| ++#define ELFMAG0		0x7f		/* Magic number byte 0 */
 | |
| ++
 | |
| ++#define EI_MAG1		1		/* File identification byte 1 index */
 | |
| ++#define ELFMAG1		'E'		/* Magic number byte 1 */
 | |
| ++
 | |
| ++#define EI_MAG2		2		/* File identification byte 2 index */
 | |
| ++#define ELFMAG2		'L'		/* Magic number byte 2 */
 | |
| ++
 | |
| ++#define EI_MAG3		3		/* File identification byte 3 index */
 | |
| ++#define ELFMAG3		'F'		/* Magic number byte 3 */
 | |
| ++
 | |
| ++/* Conglomeration of the identification bytes, for easy testing as a word.  */
 | |
| ++#define	ELFMAG		"\177ELF"
 | |
| ++#define	SELFMAG		4
 | |
| ++
 | |
| ++#define EI_CLASS	4		/* File class byte index */
 | |
| ++#define ELFCLASSNONE	0		/* Invalid class */
 | |
| ++#define ELFCLASS32	1		/* 32-bit objects */
 | |
| ++#define ELFCLASS64	2		/* 64-bit objects */
 | |
| ++#define ELFCLASSNUM	3
 | |
| ++
 | |
| ++#define EI_DATA		5		/* Data encoding byte index */
 | |
| ++#define ELFDATANONE	0		/* Invalid data encoding */
 | |
| ++#define ELFDATA2LSB	1		/* 2's complement, little endian */
 | |
| ++#define ELFDATA2MSB	2		/* 2's complement, big endian */
 | |
| ++#define ELFDATANUM	3
 | |
| ++
 | |
| ++#define EI_VERSION	6		/* File version byte index */
 | |
| ++					/* Value must be EV_CURRENT */
 | |
| ++
 | |
| ++#define EI_OSABI	7		/* OS ABI identification */
 | |
| ++#define ELFOSABI_NONE		0	/* UNIX System V ABI */
 | |
| ++#define ELFOSABI_SYSV		0	/* Alias.  */
 | |
| ++#define ELFOSABI_HPUX		1	/* HP-UX */
 | |
| ++#define ELFOSABI_NETBSD		2	/* NetBSD.  */
 | |
| ++#define ELFOSABI_GNU		3	/* Object uses GNU ELF extensions.  */
 | |
| ++#define ELFOSABI_LINUX		ELFOSABI_GNU /* Compatibility alias.  */
 | |
| ++#define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
 | |
| ++#define ELFOSABI_AIX		7	/* IBM AIX.  */
 | |
| ++#define ELFOSABI_IRIX		8	/* SGI Irix.  */
 | |
| ++#define ELFOSABI_FREEBSD	9	/* FreeBSD.  */
 | |
| ++#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
 | |
| ++#define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
 | |
| ++#define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
 | |
| ++#define ELFOSABI_ARM_AEABI	64	/* ARM EABI */
 | |
| ++#define ELFOSABI_ARM		97	/* ARM */
 | |
| ++#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
 | |
| ++
 | |
| ++#define EI_ABIVERSION	8		/* ABI version */
 | |
| ++
 | |
| ++#define EI_PAD		9		/* Byte index of padding bytes */
 | |
| ++
 | |
| ++/* Legal values for e_type (object file type).  */
 | |
| ++
 | |
| ++#define ET_NONE		0		/* No file type */
 | |
| ++#define ET_REL		1		/* Relocatable file */
 | |
| ++#define ET_EXEC		2		/* Executable file */
 | |
| ++#define ET_DYN		3		/* Shared object file */
 | |
| ++#define ET_CORE		4		/* Core file */
 | |
| ++#define	ET_NUM		5		/* Number of defined types */
 | |
| ++#define ET_LOOS		0xfe00		/* OS-specific range start */
 | |
| ++#define ET_HIOS		0xfeff		/* OS-specific range end */
 | |
| ++#define ET_LOPROC	0xff00		/* Processor-specific range start */
 | |
| ++#define ET_HIPROC	0xffff		/* Processor-specific range end */
 | |
| ++
 | |
| ++/* Legal values for e_machine (architecture).  */
 | |
| ++
 | |
| ++#define EM_NONE		 0		/* No machine */
 | |
| ++#define EM_M32		 1		/* AT&T WE 32100 */
 | |
| ++#define EM_SPARC	 2		/* SUN SPARC */
 | |
| ++#define EM_386		 3		/* Intel 80386 */
 | |
| ++#define EM_68K		 4		/* Motorola m68k family */
 | |
| ++#define EM_88K		 5		/* Motorola m88k family */
 | |
| ++#define EM_860		 7		/* Intel 80860 */
 | |
| ++#define EM_MIPS		 8		/* MIPS R3000 big-endian */
 | |
| ++#define EM_S370		 9		/* IBM System/370 */
 | |
| ++#define EM_MIPS_RS3_LE	10		/* MIPS R3000 little-endian */
 | |
| ++
 | |
| ++#define EM_PARISC	15		/* HPPA */
 | |
| ++#define EM_VPP500	17		/* Fujitsu VPP500 */
 | |
| ++#define EM_SPARC32PLUS	18		/* Sun's "v8plus" */
 | |
| ++#define EM_960		19		/* Intel 80960 */
 | |
| ++#define EM_PPC		20		/* PowerPC */
 | |
| ++#define EM_PPC64	21		/* PowerPC 64-bit */
 | |
| ++#define EM_S390		22		/* IBM S390 */
 | |
| ++
 | |
| ++#define EM_V800		36		/* NEC V800 series */
 | |
| ++#define EM_FR20		37		/* Fujitsu FR20 */
 | |
| ++#define EM_RH32		38		/* TRW RH-32 */
 | |
| ++#define EM_RCE		39		/* Motorola RCE */
 | |
| ++#define EM_ARM		40		/* ARM */
 | |
| ++#define EM_FAKE_ALPHA	41		/* Digital Alpha */
 | |
| ++#define EM_SH		42		/* Hitachi SH */
 | |
| ++#define EM_SPARCV9	43		/* SPARC v9 64-bit */
 | |
| ++#define EM_TRICORE	44		/* Siemens Tricore */
 | |
| ++#define EM_ARC		45		/* Argonaut RISC Core */
 | |
| ++#define EM_H8_300	46		/* Hitachi H8/300 */
 | |
| ++#define EM_H8_300H	47		/* Hitachi H8/300H */
 | |
| ++#define EM_H8S		48		/* Hitachi H8S */
 | |
| ++#define EM_H8_500	49		/* Hitachi H8/500 */
 | |
| ++#define EM_IA_64	50		/* Intel Merced */
 | |
| ++#define EM_MIPS_X	51		/* Stanford MIPS-X */
 | |
| ++#define EM_COLDFIRE	52		/* Motorola Coldfire */
 | |
| ++#define EM_68HC12	53		/* Motorola M68HC12 */
 | |
| ++#define EM_MMA		54		/* Fujitsu MMA Multimedia Accelerator*/
 | |
| ++#define EM_PCP		55		/* Siemens PCP */
 | |
| ++#define EM_NCPU		56		/* Sony nCPU embeeded RISC */
 | |
| ++#define EM_NDR1		57		/* Denso NDR1 microprocessor */
 | |
| ++#define EM_STARCORE	58		/* Motorola Start*Core processor */
 | |
| ++#define EM_ME16		59		/* Toyota ME16 processor */
 | |
| ++#define EM_ST100	60		/* STMicroelectronic ST100 processor */
 | |
| ++#define EM_TINYJ	61		/* Advanced Logic Corp. Tinyj emb.fam*/
 | |
| ++#define EM_X86_64	62		/* AMD x86-64 architecture */
 | |
| ++#define EM_PDSP		63		/* Sony DSP Processor */
 | |
| ++
 | |
| ++#define EM_FX66		66		/* Siemens FX66 microcontroller */
 | |
| ++#define EM_ST9PLUS	67		/* STMicroelectronics ST9+ 8/16 mc */
 | |
| ++#define EM_ST7		68		/* STmicroelectronics ST7 8 bit mc */
 | |
| ++#define EM_68HC16	69		/* Motorola MC68HC16 microcontroller */
 | |
| ++#define EM_68HC11	70		/* Motorola MC68HC11 microcontroller */
 | |
| ++#define EM_68HC08	71		/* Motorola MC68HC08 microcontroller */
 | |
| ++#define EM_68HC05	72		/* Motorola MC68HC05 microcontroller */
 | |
| ++#define EM_SVX		73		/* Silicon Graphics SVx */
 | |
| ++#define EM_ST19		74		/* STMicroelectronics ST19 8 bit mc */
 | |
| ++#define EM_VAX		75		/* Digital VAX */
 | |
| ++#define EM_CRIS		76		/* Axis Communications 32-bit embedded processor */
 | |
| ++#define EM_JAVELIN	77		/* Infineon Technologies 32-bit embedded processor */
 | |
| ++#define EM_FIREPATH	78		/* Element 14 64-bit DSP Processor */
 | |
| ++#define EM_ZSP		79		/* LSI Logic 16-bit DSP Processor */
 | |
| ++#define EM_MMIX		80		/* Donald Knuth's educational 64-bit processor */
 | |
| ++#define EM_HUANY	81		/* Harvard University machine-independent object files */
 | |
| ++#define EM_PRISM	82		/* SiTera Prism */
 | |
| ++#define EM_AVR		83		/* Atmel AVR 8-bit microcontroller */
 | |
| ++#define EM_FR30		84		/* Fujitsu FR30 */
 | |
| ++#define EM_D10V		85		/* Mitsubishi D10V */
 | |
| ++#define EM_D30V		86		/* Mitsubishi D30V */
 | |
| ++#define EM_V850		87		/* NEC v850 */
 | |
| ++#define EM_M32R		88		/* Mitsubishi M32R */
 | |
| ++#define EM_MN10300	89		/* Matsushita MN10300 */
 | |
| ++#define EM_MN10200	90		/* Matsushita MN10200 */
 | |
| ++#define EM_PJ		91		/* picoJava */
 | |
| ++#define EM_OPENRISC	92		/* OpenRISC 32-bit embedded processor */
 | |
| ++#define EM_ARC_A5	93		/* ARC Cores Tangent-A5 */
 | |
| ++#define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
 | |
| ++#define EM_TILEPRO	188		/* Tilera TILEPro */
 | |
| ++#define EM_TILEGX	191		/* Tilera TILE-Gx */
 | |
| ++#define EM_NUM		192
 | |
| ++
 | |
| ++/* If it is necessary to assign new unofficial EM_* values, please
 | |
| ++   pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
 | |
| ++   chances of collision with official or non-GNU unofficial values.  */
 | |
| ++
 | |
| ++#define EM_ALPHA	0x9026
 | |
| ++
 | |
| ++/* Legal values for e_version (version).  */
 | |
| ++
 | |
| ++#define EV_NONE		0		/* Invalid ELF version */
 | |
| ++#define EV_CURRENT	1		/* Current version */
 | |
| ++#define EV_NUM		2
 | |
| ++
 | |
| ++/* Section header.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word	sh_name;		/* Section name (string tbl index) */
 | |
| ++  Elf32_Word	sh_type;		/* Section type */
 | |
| ++  Elf32_Word	sh_flags;		/* Section flags */
 | |
| ++  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
 | |
| ++  Elf32_Off	sh_offset;		/* Section file offset */
 | |
| ++  Elf32_Word	sh_size;		/* Section size in bytes */
 | |
| ++  Elf32_Word	sh_link;		/* Link to another section */
 | |
| ++  Elf32_Word	sh_info;		/* Additional section information */
 | |
| ++  Elf32_Word	sh_addralign;		/* Section alignment */
 | |
| ++  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
 | |
| ++} Elf32_Shdr;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Word	sh_name;		/* Section name (string tbl index) */
 | |
| ++  Elf64_Word	sh_type;		/* Section type */
 | |
| ++  Elf64_Xword	sh_flags;		/* Section flags */
 | |
| ++  Elf64_Addr	sh_addr;		/* Section virtual addr at execution */
 | |
| ++  Elf64_Off	sh_offset;		/* Section file offset */
 | |
| ++  Elf64_Xword	sh_size;		/* Section size in bytes */
 | |
| ++  Elf64_Word	sh_link;		/* Link to another section */
 | |
| ++  Elf64_Word	sh_info;		/* Additional section information */
 | |
| ++  Elf64_Xword	sh_addralign;		/* Section alignment */
 | |
| ++  Elf64_Xword	sh_entsize;		/* Entry size if section holds table */
 | |
| ++} Elf64_Shdr;
 | |
| ++
 | |
| ++/* Special section indices.  */
 | |
| ++
 | |
| ++#define SHN_UNDEF	0		/* Undefined section */
 | |
| ++#define SHN_LORESERVE	0xff00		/* Start of reserved indices */
 | |
| ++#define SHN_LOPROC	0xff00		/* Start of processor-specific */
 | |
| ++#define SHN_BEFORE	0xff00		/* Order section before all others
 | |
| ++					   (Solaris).  */
 | |
| ++#define SHN_AFTER	0xff01		/* Order section after all others
 | |
| ++					   (Solaris).  */
 | |
| ++#define SHN_HIPROC	0xff1f		/* End of processor-specific */
 | |
| ++#define SHN_LOOS	0xff20		/* Start of OS-specific */
 | |
| ++#define SHN_HIOS	0xff3f		/* End of OS-specific */
 | |
| ++#define SHN_ABS		0xfff1		/* Associated symbol is absolute */
 | |
| ++#define SHN_COMMON	0xfff2		/* Associated symbol is common */
 | |
| ++#define SHN_XINDEX	0xffff		/* Index is in extra table.  */
 | |
| ++#define SHN_HIRESERVE	0xffff		/* End of reserved indices */
 | |
| ++
 | |
| ++/* Legal values for sh_type (section type).  */
 | |
| ++
 | |
| ++#define SHT_NULL	  0		/* Section header table entry unused */
 | |
| ++#define SHT_PROGBITS	  1		/* Program data */
 | |
| ++#define SHT_SYMTAB	  2		/* Symbol table */
 | |
| ++#define SHT_STRTAB	  3		/* String table */
 | |
| ++#define SHT_RELA	  4		/* Relocation entries with addends */
 | |
| ++#define SHT_HASH	  5		/* Symbol hash table */
 | |
| ++#define SHT_DYNAMIC	  6		/* Dynamic linking information */
 | |
| ++#define SHT_NOTE	  7		/* Notes */
 | |
| ++#define SHT_NOBITS	  8		/* Program space with no data (bss) */
 | |
| ++#define SHT_REL		  9		/* Relocation entries, no addends */
 | |
| ++#define SHT_SHLIB	  10		/* Reserved */
 | |
| ++#define SHT_DYNSYM	  11		/* Dynamic linker symbol table */
 | |
| ++#define SHT_INIT_ARRAY	  14		/* Array of constructors */
 | |
| ++#define SHT_FINI_ARRAY	  15		/* Array of destructors */
 | |
| ++#define SHT_PREINIT_ARRAY 16		/* Array of pre-constructors */
 | |
| ++#define SHT_GROUP	  17		/* Section group */
 | |
| ++#define SHT_SYMTAB_SHNDX  18		/* Extended section indeces */
 | |
| ++#define	SHT_NUM		  19		/* Number of defined types.  */
 | |
| ++#define SHT_LOOS	  0x60000000	/* Start OS-specific.  */
 | |
| ++#define SHT_GNU_ATTRIBUTES 0x6ffffff5	/* Object attributes.  */
 | |
| ++#define SHT_GNU_HASH	  0x6ffffff6	/* GNU-style hash table.  */
 | |
| ++#define SHT_GNU_LIBLIST	  0x6ffffff7	/* Prelink library list */
 | |
| ++#define SHT_CHECKSUM	  0x6ffffff8	/* Checksum for DSO content.  */
 | |
| ++#define SHT_LOSUNW	  0x6ffffffa	/* Sun-specific low bound.  */
 | |
| ++#define SHT_SUNW_move	  0x6ffffffa
 | |
| ++#define SHT_SUNW_COMDAT   0x6ffffffb
 | |
| ++#define SHT_SUNW_syminfo  0x6ffffffc
 | |
| ++#define SHT_GNU_verdef	  0x6ffffffd	/* Version definition section.  */
 | |
| ++#define SHT_GNU_verneed	  0x6ffffffe	/* Version needs section.  */
 | |
| ++#define SHT_GNU_versym	  0x6fffffff	/* Version symbol table.  */
 | |
| ++#define SHT_HISUNW	  0x6fffffff	/* Sun-specific high bound.  */
 | |
| ++#define SHT_HIOS	  0x6fffffff	/* End OS-specific type */
 | |
| ++#define SHT_LOPROC	  0x70000000	/* Start of processor-specific */
 | |
| ++#define SHT_HIPROC	  0x7fffffff	/* End of processor-specific */
 | |
| ++#define SHT_LOUSER	  0x80000000	/* Start of application-specific */
 | |
| ++#define SHT_HIUSER	  0x8fffffff	/* End of application-specific */
 | |
| ++
 | |
| ++/* Legal values for sh_flags (section flags).  */
 | |
| ++
 | |
| ++#define SHF_WRITE	     (1 << 0)	/* Writable */
 | |
| ++#define SHF_ALLOC	     (1 << 1)	/* Occupies memory during execution */
 | |
| ++#define SHF_EXECINSTR	     (1 << 2)	/* Executable */
 | |
| ++#define SHF_MERGE	     (1 << 4)	/* Might be merged */
 | |
| ++#define SHF_STRINGS	     (1 << 5)	/* Contains nul-terminated strings */
 | |
| ++#define SHF_INFO_LINK	     (1 << 6)	/* `sh_info' contains SHT index */
 | |
| ++#define SHF_LINK_ORDER	     (1 << 7)	/* Preserve order after combining */
 | |
| ++#define SHF_OS_NONCONFORMING (1 << 8)	/* Non-standard OS specific handling
 | |
| ++					   required */
 | |
| ++#define SHF_GROUP	     (1 << 9)	/* Section is member of a group.  */
 | |
| ++#define SHF_TLS		     (1 << 10)	/* Section hold thread-local data.  */
 | |
| ++#define SHF_MASKOS	     0x0ff00000	/* OS-specific.  */
 | |
| ++#define SHF_MASKPROC	     0xf0000000	/* Processor-specific */
 | |
| ++#define SHF_ORDERED	     (1 << 30)	/* Special ordering requirement
 | |
| ++					   (Solaris).  */
 | |
| ++#define SHF_EXCLUDE	     (1 << 31)	/* Section is excluded unless
 | |
| ++					   referenced or allocated (Solaris).*/
 | |
| ++
 | |
| ++/* Section group handling.  */
 | |
| ++#define GRP_COMDAT	0x1		/* Mark group as COMDAT.  */
 | |
| ++
 | |
| ++/* Symbol table entry.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word	st_name;		/* Symbol name (string tbl index) */
 | |
| ++  Elf32_Addr	st_value;		/* Symbol value */
 | |
| ++  Elf32_Word	st_size;		/* Symbol size */
 | |
| ++  unsigned char	st_info;		/* Symbol type and binding */
 | |
| ++  unsigned char	st_other;		/* Symbol visibility */
 | |
| ++  Elf32_Section	st_shndx;		/* Section index */
 | |
| ++} Elf32_Sym;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Word	st_name;		/* Symbol name (string tbl index) */
 | |
| ++  unsigned char	st_info;		/* Symbol type and binding */
 | |
| ++  unsigned char st_other;		/* Symbol visibility */
 | |
| ++  Elf64_Section	st_shndx;		/* Section index */
 | |
| ++  Elf64_Addr	st_value;		/* Symbol value */
 | |
| ++  Elf64_Xword	st_size;		/* Symbol size */
 | |
| ++} Elf64_Sym;
 | |
| ++
 | |
| ++/* The syminfo section if available contains additional information about
 | |
| ++   every dynamic symbol.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Half si_boundto;		/* Direct bindings, symbol bound to */
 | |
| ++  Elf32_Half si_flags;			/* Per symbol flags */
 | |
| ++} Elf32_Syminfo;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Half si_boundto;		/* Direct bindings, symbol bound to */
 | |
| ++  Elf64_Half si_flags;			/* Per symbol flags */
 | |
| ++} Elf64_Syminfo;
 | |
| ++
 | |
| ++/* Possible values for si_boundto.  */
 | |
| ++#define SYMINFO_BT_SELF		0xffff	/* Symbol bound to self */
 | |
| ++#define SYMINFO_BT_PARENT	0xfffe	/* Symbol bound to parent */
 | |
| ++#define SYMINFO_BT_LOWRESERVE	0xff00	/* Beginning of reserved entries */
 | |
| ++
 | |
| ++/* Possible bitmasks for si_flags.  */
 | |
| ++#define SYMINFO_FLG_DIRECT	0x0001	/* Direct bound symbol */
 | |
| ++#define SYMINFO_FLG_PASSTHRU	0x0002	/* Pass-thru symbol for translator */
 | |
| ++#define SYMINFO_FLG_COPY	0x0004	/* Symbol is a copy-reloc */
 | |
| ++#define SYMINFO_FLG_LAZYLOAD	0x0008	/* Symbol bound to object to be lazy
 | |
| ++					   loaded */
 | |
| ++/* Syminfo version values.  */
 | |
| ++#define SYMINFO_NONE		0
 | |
| ++#define SYMINFO_CURRENT		1
 | |
| ++#define SYMINFO_NUM		2
 | |
| ++
 | |
| ++
 | |
| ++/* How to extract and insert information held in the st_info field.  */
 | |
| ++
 | |
| ++#define ELF32_ST_BIND(val)		(((unsigned char) (val)) >> 4)
 | |
| ++#define ELF32_ST_TYPE(val)		((val) & 0xf)
 | |
| ++#define ELF32_ST_INFO(bind, type)	(((bind) << 4) + ((type) & 0xf))
 | |
| ++
 | |
| ++/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field.  */
 | |
| ++#define ELF64_ST_BIND(val)		ELF32_ST_BIND (val)
 | |
| ++#define ELF64_ST_TYPE(val)		ELF32_ST_TYPE (val)
 | |
| ++#define ELF64_ST_INFO(bind, type)	ELF32_ST_INFO ((bind), (type))
 | |
| ++
 | |
| ++/* Legal values for ST_BIND subfield of st_info (symbol binding).  */
 | |
| ++
 | |
| ++#define STB_LOCAL	0		/* Local symbol */
 | |
| ++#define STB_GLOBAL	1		/* Global symbol */
 | |
| ++#define STB_WEAK	2		/* Weak symbol */
 | |
| ++#define	STB_NUM		3		/* Number of defined types.  */
 | |
| ++#define STB_LOOS	10		/* Start of OS-specific */
 | |
| ++#define STB_GNU_UNIQUE	10		/* Unique symbol.  */
 | |
| ++#define STB_HIOS	12		/* End of OS-specific */
 | |
| ++#define STB_LOPROC	13		/* Start of processor-specific */
 | |
| ++#define STB_HIPROC	15		/* End of processor-specific */
 | |
| ++
 | |
| ++/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
 | |
| ++
 | |
| ++#define STT_NOTYPE	0		/* Symbol type is unspecified */
 | |
| ++#define STT_OBJECT	1		/* Symbol is a data object */
 | |
| ++#define STT_FUNC	2		/* Symbol is a code object */
 | |
| ++#define STT_SECTION	3		/* Symbol associated with a section */
 | |
| ++#define STT_FILE	4		/* Symbol's name is file name */
 | |
| ++#define STT_COMMON	5		/* Symbol is a common data object */
 | |
| ++#define STT_TLS		6		/* Symbol is thread-local data object*/
 | |
| ++#define	STT_NUM		7		/* Number of defined types.  */
 | |
| ++#define STT_LOOS	10		/* Start of OS-specific */
 | |
| ++#define STT_GNU_IFUNC	10		/* Symbol is indirect code object */
 | |
| ++#define STT_HIOS	12		/* End of OS-specific */
 | |
| ++#define STT_LOPROC	13		/* Start of processor-specific */
 | |
| ++#define STT_HIPROC	15		/* End of processor-specific */
 | |
| ++
 | |
| ++
 | |
| ++/* Symbol table indices are found in the hash buckets and chain table
 | |
| ++   of a symbol hash table section.  This special index value indicates
 | |
| ++   the end of a chain, meaning no further symbols are found in that bucket.  */
 | |
| ++
 | |
| ++#define STN_UNDEF	0		/* End of a chain.  */
 | |
| ++
 | |
| ++
 | |
| ++/* How to extract and insert information held in the st_other field.  */
 | |
| ++
 | |
| ++#define ELF32_ST_VISIBILITY(o)	((o) & 0x03)
 | |
| ++
 | |
| ++/* For ELF64 the definitions are the same.  */
 | |
| ++#define ELF64_ST_VISIBILITY(o)	ELF32_ST_VISIBILITY (o)
 | |
| ++
 | |
| ++/* Symbol visibility specification encoded in the st_other field.  */
 | |
| ++#define STV_DEFAULT	0		/* Default symbol visibility rules */
 | |
| ++#define STV_INTERNAL	1		/* Processor specific hidden class */
 | |
| ++#define STV_HIDDEN	2		/* Sym unavailable in other modules */
 | |
| ++#define STV_PROTECTED	3		/* Not preemptible, not exported */
 | |
| ++
 | |
| ++
 | |
| ++/* Relocation table entry without addend (in section of type SHT_REL).  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Addr	r_offset;		/* Address */
 | |
| ++  Elf32_Word	r_info;			/* Relocation type and symbol index */
 | |
| ++} Elf32_Rel;
 | |
| ++
 | |
| ++/* I have seen two different definitions of the Elf64_Rel and
 | |
| ++   Elf64_Rela structures, so we'll leave them out until Novell (or
 | |
| ++   whoever) gets their act together.  */
 | |
| ++/* The following, at least, is used on Sparc v9, MIPS, and Alpha.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Addr	r_offset;		/* Address */
 | |
| ++  Elf64_Xword	r_info;			/* Relocation type and symbol index */
 | |
| ++} Elf64_Rel;
 | |
| ++
 | |
| ++/* Relocation table entry with addend (in section of type SHT_RELA).  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Addr	r_offset;		/* Address */
 | |
| ++  Elf32_Word	r_info;			/* Relocation type and symbol index */
 | |
| ++  Elf32_Sword	r_addend;		/* Addend */
 | |
| ++} Elf32_Rela;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Addr	r_offset;		/* Address */
 | |
| ++  Elf64_Xword	r_info;			/* Relocation type and symbol index */
 | |
| ++  Elf64_Sxword	r_addend;		/* Addend */
 | |
| ++} Elf64_Rela;
 | |
| ++
 | |
| ++/* How to extract and insert information held in the r_info field.  */
 | |
| ++
 | |
| ++#define ELF32_R_SYM(val)		((val) >> 8)
 | |
| ++#define ELF32_R_TYPE(val)		((val) & 0xff)
 | |
| ++#define ELF32_R_INFO(sym, type)		(((sym) << 8) + ((type) & 0xff))
 | |
| ++
 | |
| ++#define ELF64_R_SYM(i)			((i) >> 32)
 | |
| ++#define ELF64_R_TYPE(i)			((i) & 0xffffffff)
 | |
| ++#define ELF64_R_INFO(sym,type)		((((Elf64_Xword) (sym)) << 32) + (type))
 | |
| ++
 | |
| ++/* Program segment header.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word	p_type;			/* Segment type */
 | |
| ++  Elf32_Off	p_offset;		/* Segment file offset */
 | |
| ++  Elf32_Addr	p_vaddr;		/* Segment virtual address */
 | |
| ++  Elf32_Addr	p_paddr;		/* Segment physical address */
 | |
| ++  Elf32_Word	p_filesz;		/* Segment size in file */
 | |
| ++  Elf32_Word	p_memsz;		/* Segment size in memory */
 | |
| ++  Elf32_Word	p_flags;		/* Segment flags */
 | |
| ++  Elf32_Word	p_align;		/* Segment alignment */
 | |
| ++} Elf32_Phdr;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Word	p_type;			/* Segment type */
 | |
| ++  Elf64_Word	p_flags;		/* Segment flags */
 | |
| ++  Elf64_Off	p_offset;		/* Segment file offset */
 | |
| ++  Elf64_Addr	p_vaddr;		/* Segment virtual address */
 | |
| ++  Elf64_Addr	p_paddr;		/* Segment physical address */
 | |
| ++  Elf64_Xword	p_filesz;		/* Segment size in file */
 | |
| ++  Elf64_Xword	p_memsz;		/* Segment size in memory */
 | |
| ++  Elf64_Xword	p_align;		/* Segment alignment */
 | |
| ++} Elf64_Phdr;
 | |
| ++
 | |
| ++/* Special value for e_phnum.  This indicates that the real number of
 | |
| ++   program headers is too large to fit into e_phnum.  Instead the real
 | |
| ++   value is in the field sh_info of section 0.  */
 | |
| ++
 | |
| ++#define PN_XNUM		0xffff
 | |
| ++
 | |
| ++/* Legal values for p_type (segment type).  */
 | |
| ++
 | |
| ++#define	PT_NULL		0		/* Program header table entry unused */
 | |
| ++#define PT_LOAD		1		/* Loadable program segment */
 | |
| ++#define PT_DYNAMIC	2		/* Dynamic linking information */
 | |
| ++#define PT_INTERP	3		/* Program interpreter */
 | |
| ++#define PT_NOTE		4		/* Auxiliary information */
 | |
| ++#define PT_SHLIB	5		/* Reserved */
 | |
| ++#define PT_PHDR		6		/* Entry for header table itself */
 | |
| ++#define PT_TLS		7		/* Thread-local storage segment */
 | |
| ++#define	PT_NUM		8		/* Number of defined types */
 | |
| ++#define PT_LOOS		0x60000000	/* Start of OS-specific */
 | |
| ++#define PT_GNU_EH_FRAME	0x6474e550	/* GCC .eh_frame_hdr segment */
 | |
| ++#define PT_GNU_STACK	0x6474e551	/* Indicates stack executability */
 | |
| ++#define PT_GNU_RELRO	0x6474e552	/* Read-only after relocation */
 | |
| ++#define PT_LOSUNW	0x6ffffffa
 | |
| ++#define PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
 | |
| ++#define PT_SUNWSTACK	0x6ffffffb	/* Stack segment */
 | |
| ++#define PT_HISUNW	0x6fffffff
 | |
| ++#define PT_HIOS		0x6fffffff	/* End of OS-specific */
 | |
| ++#define PT_LOPROC	0x70000000	/* Start of processor-specific */
 | |
| ++#define PT_HIPROC	0x7fffffff	/* End of processor-specific */
 | |
| ++
 | |
| ++/* Legal values for p_flags (segment flags).  */
 | |
| ++
 | |
| ++#define PF_X		(1 << 0)	/* Segment is executable */
 | |
| ++#define PF_W		(1 << 1)	/* Segment is writable */
 | |
| ++#define PF_R		(1 << 2)	/* Segment is readable */
 | |
| ++#define PF_MASKOS	0x0ff00000	/* OS-specific */
 | |
| ++#define PF_MASKPROC	0xf0000000	/* Processor-specific */
 | |
| ++
 | |
| ++/* Legal values for note segment descriptor types for core files. */
 | |
| ++
 | |
| ++#define NT_PRSTATUS	1		/* Contains copy of prstatus struct */
 | |
| ++#define NT_FPREGSET	2		/* Contains copy of fpregset struct */
 | |
| ++#define NT_PRPSINFO	3		/* Contains copy of prpsinfo struct */
 | |
| ++#define NT_PRXREG	4		/* Contains copy of prxregset struct */
 | |
| ++#define NT_TASKSTRUCT	4		/* Contains copy of task structure */
 | |
| ++#define NT_PLATFORM	5		/* String from sysinfo(SI_PLATFORM) */
 | |
| ++#define NT_AUXV		6		/* Contains copy of auxv array */
 | |
| ++#define NT_GWINDOWS	7		/* Contains copy of gwindows struct */
 | |
| ++#define NT_ASRS		8		/* Contains copy of asrset struct */
 | |
| ++#define NT_PSTATUS	10		/* Contains copy of pstatus struct */
 | |
| ++#define NT_PSINFO	13		/* Contains copy of psinfo struct */
 | |
| ++#define NT_PRCRED	14		/* Contains copy of prcred struct */
 | |
| ++#define NT_UTSNAME	15		/* Contains copy of utsname struct */
 | |
| ++#define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
 | |
| ++#define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
 | |
| ++#define NT_PRFPXREG	20		/* Contains copy of fprxregset struct */
 | |
| ++#define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
 | |
| ++#define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
 | |
| ++#define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
 | |
| ++#define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
 | |
| ++#define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
 | |
| ++#define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
 | |
| ++#define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
 | |
| ++
 | |
| ++/* Legal values for the note segment descriptor types for object files.  */
 | |
| ++
 | |
| ++#define NT_VERSION	1		/* Contains a version string.  */
 | |
| ++
 | |
| ++
 | |
| ++/* Dynamic section entry.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Sword	d_tag;			/* Dynamic entry type */
 | |
| ++  union
 | |
| ++    {
 | |
| ++      Elf32_Word d_val;			/* Integer value */
 | |
| ++      Elf32_Addr d_ptr;			/* Address value */
 | |
| ++    } d_un;
 | |
| ++} Elf32_Dyn;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Sxword	d_tag;			/* Dynamic entry type */
 | |
| ++  union
 | |
| ++    {
 | |
| ++      Elf64_Xword d_val;		/* Integer value */
 | |
| ++      Elf64_Addr d_ptr;			/* Address value */
 | |
| ++    } d_un;
 | |
| ++} Elf64_Dyn;
 | |
| ++
 | |
| ++/* Legal values for d_tag (dynamic entry type).  */
 | |
| ++
 | |
| ++#define DT_NULL		0		/* Marks end of dynamic section */
 | |
| ++#define DT_NEEDED	1		/* Name of needed library */
 | |
| ++#define DT_PLTRELSZ	2		/* Size in bytes of PLT relocs */
 | |
| ++#define DT_PLTGOT	3		/* Processor defined value */
 | |
| ++#define DT_HASH		4		/* Address of symbol hash table */
 | |
| ++#define DT_STRTAB	5		/* Address of string table */
 | |
| ++#define DT_SYMTAB	6		/* Address of symbol table */
 | |
| ++#define DT_RELA		7		/* Address of Rela relocs */
 | |
| ++#define DT_RELASZ	8		/* Total size of Rela relocs */
 | |
| ++#define DT_RELAENT	9		/* Size of one Rela reloc */
 | |
| ++#define DT_STRSZ	10		/* Size of string table */
 | |
| ++#define DT_SYMENT	11		/* Size of one symbol table entry */
 | |
| ++#define DT_INIT		12		/* Address of init function */
 | |
| ++#define DT_FINI		13		/* Address of termination function */
 | |
| ++#define DT_SONAME	14		/* Name of shared object */
 | |
| ++#define DT_RPATH	15		/* Library search path (deprecated) */
 | |
| ++#define DT_SYMBOLIC	16		/* Start symbol search here */
 | |
| ++#define DT_REL		17		/* Address of Rel relocs */
 | |
| ++#define DT_RELSZ	18		/* Total size of Rel relocs */
 | |
| ++#define DT_RELENT	19		/* Size of one Rel reloc */
 | |
| ++#define DT_PLTREL	20		/* Type of reloc in PLT */
 | |
| ++#define DT_DEBUG	21		/* For debugging; unspecified */
 | |
| ++#define DT_TEXTREL	22		/* Reloc might modify .text */
 | |
| ++#define DT_JMPREL	23		/* Address of PLT relocs */
 | |
| ++#define	DT_BIND_NOW	24		/* Process relocations of object */
 | |
| ++#define	DT_INIT_ARRAY	25		/* Array with addresses of init fct */
 | |
| ++#define	DT_FINI_ARRAY	26		/* Array with addresses of fini fct */
 | |
| ++#define	DT_INIT_ARRAYSZ	27		/* Size in bytes of DT_INIT_ARRAY */
 | |
| ++#define	DT_FINI_ARRAYSZ	28		/* Size in bytes of DT_FINI_ARRAY */
 | |
| ++#define DT_RUNPATH	29		/* Library search path */
 | |
| ++#define DT_FLAGS	30		/* Flags for the object being loaded */
 | |
| ++#define DT_ENCODING	32		/* Start of encoded range */
 | |
| ++#define DT_PREINIT_ARRAY 32		/* Array with addresses of preinit fct*/
 | |
| ++#define DT_PREINIT_ARRAYSZ 33		/* size in bytes of DT_PREINIT_ARRAY */
 | |
| ++#define	DT_NUM		34		/* Number used */
 | |
| ++#define DT_LOOS		0x6000000d	/* Start of OS-specific */
 | |
| ++#define DT_HIOS		0x6ffff000	/* End of OS-specific */
 | |
| ++#define DT_LOPROC	0x70000000	/* Start of processor-specific */
 | |
| ++#define DT_HIPROC	0x7fffffff	/* End of processor-specific */
 | |
| ++#define	DT_PROCNUM	DT_MIPS_NUM	/* Most used by any processor */
 | |
| ++
 | |
| ++/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
 | |
| ++   Dyn.d_un.d_val field of the Elf*_Dyn structure.  This follows Sun's
 | |
| ++   approach.  */
 | |
| ++#define DT_VALRNGLO	0x6ffffd00
 | |
| ++#define DT_GNU_PRELINKED 0x6ffffdf5	/* Prelinking timestamp */
 | |
| ++#define DT_GNU_CONFLICTSZ 0x6ffffdf6	/* Size of conflict section */
 | |
| ++#define DT_GNU_LIBLISTSZ 0x6ffffdf7	/* Size of library list */
 | |
| ++#define DT_CHECKSUM	0x6ffffdf8
 | |
| ++#define DT_PLTPADSZ	0x6ffffdf9
 | |
| ++#define DT_MOVEENT	0x6ffffdfa
 | |
| ++#define DT_MOVESZ	0x6ffffdfb
 | |
| ++#define DT_FEATURE_1	0x6ffffdfc	/* Feature selection (DTF_*).  */
 | |
| ++#define DT_POSFLAG_1	0x6ffffdfd	/* Flags for DT_* entries, effecting
 | |
| ++					   the following DT_* entry.  */
 | |
| ++#define DT_SYMINSZ	0x6ffffdfe	/* Size of syminfo table (in bytes) */
 | |
| ++#define DT_SYMINENT	0x6ffffdff	/* Entry size of syminfo */
 | |
| ++#define DT_VALRNGHI	0x6ffffdff
 | |
| ++#define DT_VALTAGIDX(tag)	(DT_VALRNGHI - (tag))	/* Reverse order! */
 | |
| ++#define DT_VALNUM 12
 | |
| ++
 | |
| ++/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
 | |
| ++   Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
 | |
| ++
 | |
| ++   If any adjustment is made to the ELF object after it has been
 | |
| ++   built these entries will need to be adjusted.  */
 | |
| ++#define DT_ADDRRNGLO	0x6ffffe00
 | |
| ++#define DT_GNU_HASH	0x6ffffef5	/* GNU-style hash table.  */
 | |
| ++#define DT_TLSDESC_PLT	0x6ffffef6
 | |
| ++#define DT_TLSDESC_GOT	0x6ffffef7
 | |
| ++#define DT_GNU_CONFLICT	0x6ffffef8	/* Start of conflict section */
 | |
| ++#define DT_GNU_LIBLIST	0x6ffffef9	/* Library list */
 | |
| ++#define DT_CONFIG	0x6ffffefa	/* Configuration information.  */
 | |
| ++#define DT_DEPAUDIT	0x6ffffefb	/* Dependency auditing.  */
 | |
| ++#define DT_AUDIT	0x6ffffefc	/* Object auditing.  */
 | |
| ++#define	DT_PLTPAD	0x6ffffefd	/* PLT padding.  */
 | |
| ++#define	DT_MOVETAB	0x6ffffefe	/* Move table.  */
 | |
| ++#define DT_SYMINFO	0x6ffffeff	/* Syminfo table.  */
 | |
| ++#define DT_ADDRRNGHI	0x6ffffeff
 | |
| ++#define DT_ADDRTAGIDX(tag)	(DT_ADDRRNGHI - (tag))	/* Reverse order! */
 | |
| ++#define DT_ADDRNUM 11
 | |
| ++
 | |
| ++/* The versioning entry types.  The next are defined as part of the
 | |
| ++   GNU extension.  */
 | |
| ++#define DT_VERSYM	0x6ffffff0
 | |
| ++
 | |
| ++#define DT_RELACOUNT	0x6ffffff9
 | |
| ++#define DT_RELCOUNT	0x6ffffffa
 | |
| ++
 | |
| ++/* These were chosen by Sun.  */
 | |
| ++#define DT_FLAGS_1	0x6ffffffb	/* State flags, see DF_1_* below.  */
 | |
| ++#define	DT_VERDEF	0x6ffffffc	/* Address of version definition
 | |
| ++					   table */
 | |
| ++#define	DT_VERDEFNUM	0x6ffffffd	/* Number of version definitions */
 | |
| ++#define	DT_VERNEED	0x6ffffffe	/* Address of table with needed
 | |
| ++					   versions */
 | |
| ++#define	DT_VERNEEDNUM	0x6fffffff	/* Number of needed versions */
 | |
| ++#define DT_VERSIONTAGIDX(tag)	(DT_VERNEEDNUM - (tag))	/* Reverse order! */
 | |
| ++#define DT_VERSIONTAGNUM 16
 | |
| ++
 | |
| ++/* Sun added these machine-independent extensions in the "processor-specific"
 | |
| ++   range.  Be compatible.  */
 | |
| ++#define DT_AUXILIARY    0x7ffffffd      /* Shared object to load before self */
 | |
| ++#define DT_FILTER       0x7fffffff      /* Shared object to get values from */
 | |
| ++#define DT_EXTRATAGIDX(tag)	((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
 | |
| ++#define DT_EXTRANUM	3
 | |
| ++
 | |
| ++/* Values of `d_un.d_val' in the DT_FLAGS entry.  */
 | |
| ++#define DF_ORIGIN	0x00000001	/* Object may use DF_ORIGIN */
 | |
| ++#define DF_SYMBOLIC	0x00000002	/* Symbol resolutions starts here */
 | |
| ++#define DF_TEXTREL	0x00000004	/* Object contains text relocations */
 | |
| ++#define DF_BIND_NOW	0x00000008	/* No lazy binding for this object */
 | |
| ++#define DF_STATIC_TLS	0x00000010	/* Module uses the static TLS model */
 | |
| ++
 | |
| ++/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
 | |
| ++   entry in the dynamic section.  */
 | |
| ++#define DF_1_NOW	0x00000001	/* Set RTLD_NOW for this object.  */
 | |
| ++#define DF_1_GLOBAL	0x00000002	/* Set RTLD_GLOBAL for this object.  */
 | |
| ++#define DF_1_GROUP	0x00000004	/* Set RTLD_GROUP for this object.  */
 | |
| ++#define DF_1_NODELETE	0x00000008	/* Set RTLD_NODELETE for this object.*/
 | |
| ++#define DF_1_LOADFLTR	0x00000010	/* Trigger filtee loading at runtime.*/
 | |
| ++#define DF_1_INITFIRST	0x00000020	/* Set RTLD_INITFIRST for this object*/
 | |
| ++#define DF_1_NOOPEN	0x00000040	/* Set RTLD_NOOPEN for this object.  */
 | |
| ++#define DF_1_ORIGIN	0x00000080	/* $ORIGIN must be handled.  */
 | |
| ++#define DF_1_DIRECT	0x00000100	/* Direct binding enabled.  */
 | |
| ++#define DF_1_TRANS	0x00000200
 | |
| ++#define DF_1_INTERPOSE	0x00000400	/* Object is used to interpose.  */
 | |
| ++#define DF_1_NODEFLIB	0x00000800	/* Ignore default lib search path.  */
 | |
| ++#define DF_1_NODUMP	0x00001000	/* Object can't be dldump'ed.  */
 | |
| ++#define DF_1_CONFALT	0x00002000	/* Configuration alternative created.*/
 | |
| ++#define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
 | |
| ++#define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
 | |
| ++#define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
 | |
| ++
 | |
| ++/* Flags for the feature selection in DT_FEATURE_1.  */
 | |
| ++#define DTF_1_PARINIT	0x00000001
 | |
| ++#define DTF_1_CONFEXP	0x00000002
 | |
| ++
 | |
| ++/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry.  */
 | |
| ++#define DF_P1_LAZYLOAD	0x00000001	/* Lazyload following object.  */
 | |
| ++#define DF_P1_GROUPPERM	0x00000002	/* Symbols from next object are not
 | |
| ++					   generally available.  */
 | |
| ++
 | |
| ++/* Version definition sections.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Half	vd_version;		/* Version revision */
 | |
| ++  Elf32_Half	vd_flags;		/* Version information */
 | |
| ++  Elf32_Half	vd_ndx;			/* Version Index */
 | |
| ++  Elf32_Half	vd_cnt;			/* Number of associated aux entries */
 | |
| ++  Elf32_Word	vd_hash;		/* Version name hash value */
 | |
| ++  Elf32_Word	vd_aux;			/* Offset in bytes to verdaux array */
 | |
| ++  Elf32_Word	vd_next;		/* Offset in bytes to next verdef
 | |
| ++					   entry */
 | |
| ++} Elf32_Verdef;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Half	vd_version;		/* Version revision */
 | |
| ++  Elf64_Half	vd_flags;		/* Version information */
 | |
| ++  Elf64_Half	vd_ndx;			/* Version Index */
 | |
| ++  Elf64_Half	vd_cnt;			/* Number of associated aux entries */
 | |
| ++  Elf64_Word	vd_hash;		/* Version name hash value */
 | |
| ++  Elf64_Word	vd_aux;			/* Offset in bytes to verdaux array */
 | |
| ++  Elf64_Word	vd_next;		/* Offset in bytes to next verdef
 | |
| ++					   entry */
 | |
| ++} Elf64_Verdef;
 | |
| ++
 | |
| ++
 | |
| ++/* Legal values for vd_version (version revision).  */
 | |
| ++#define VER_DEF_NONE	0		/* No version */
 | |
| ++#define VER_DEF_CURRENT	1		/* Current version */
 | |
| ++#define VER_DEF_NUM	2		/* Given version number */
 | |
| ++
 | |
| ++/* Legal values for vd_flags (version information flags).  */
 | |
| ++#define VER_FLG_BASE	0x1		/* Version definition of file itself */
 | |
| ++#define VER_FLG_WEAK	0x2		/* Weak version identifier */
 | |
| ++
 | |
| ++/* Versym symbol index values.  */
 | |
| ++#define	VER_NDX_LOCAL		0	/* Symbol is local.  */
 | |
| ++#define	VER_NDX_GLOBAL		1	/* Symbol is global.  */
 | |
| ++#define	VER_NDX_LORESERVE	0xff00	/* Beginning of reserved entries.  */
 | |
| ++#define	VER_NDX_ELIMINATE	0xff01	/* Symbol is to be eliminated.  */
 | |
| ++
 | |
| ++/* Auxialiary version information.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word	vda_name;		/* Version or dependency names */
 | |
| ++  Elf32_Word	vda_next;		/* Offset in bytes to next verdaux
 | |
| ++					   entry */
 | |
| ++} Elf32_Verdaux;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Word	vda_name;		/* Version or dependency names */
 | |
| ++  Elf64_Word	vda_next;		/* Offset in bytes to next verdaux
 | |
| ++					   entry */
 | |
| ++} Elf64_Verdaux;
 | |
| ++
 | |
| ++
 | |
| ++/* Version dependency section.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Half	vn_version;		/* Version of structure */
 | |
| ++  Elf32_Half	vn_cnt;			/* Number of associated aux entries */
 | |
| ++  Elf32_Word	vn_file;		/* Offset of filename for this
 | |
| ++					   dependency */
 | |
| ++  Elf32_Word	vn_aux;			/* Offset in bytes to vernaux array */
 | |
| ++  Elf32_Word	vn_next;		/* Offset in bytes to next verneed
 | |
| ++					   entry */
 | |
| ++} Elf32_Verneed;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Half	vn_version;		/* Version of structure */
 | |
| ++  Elf64_Half	vn_cnt;			/* Number of associated aux entries */
 | |
| ++  Elf64_Word	vn_file;		/* Offset of filename for this
 | |
| ++					   dependency */
 | |
| ++  Elf64_Word	vn_aux;			/* Offset in bytes to vernaux array */
 | |
| ++  Elf64_Word	vn_next;		/* Offset in bytes to next verneed
 | |
| ++					   entry */
 | |
| ++} Elf64_Verneed;
 | |
| ++
 | |
| ++
 | |
| ++/* Legal values for vn_version (version revision).  */
 | |
| ++#define VER_NEED_NONE	 0		/* No version */
 | |
| ++#define VER_NEED_CURRENT 1		/* Current version */
 | |
| ++#define VER_NEED_NUM	 2		/* Given version number */
 | |
| ++
 | |
| ++/* Auxiliary needed version information.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word	vna_hash;		/* Hash value of dependency name */
 | |
| ++  Elf32_Half	vna_flags;		/* Dependency specific information */
 | |
| ++  Elf32_Half	vna_other;		/* Unused */
 | |
| ++  Elf32_Word	vna_name;		/* Dependency name string offset */
 | |
| ++  Elf32_Word	vna_next;		/* Offset in bytes to next vernaux
 | |
| ++					   entry */
 | |
| ++} Elf32_Vernaux;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Word	vna_hash;		/* Hash value of dependency name */
 | |
| ++  Elf64_Half	vna_flags;		/* Dependency specific information */
 | |
| ++  Elf64_Half	vna_other;		/* Unused */
 | |
| ++  Elf64_Word	vna_name;		/* Dependency name string offset */
 | |
| ++  Elf64_Word	vna_next;		/* Offset in bytes to next vernaux
 | |
| ++					   entry */
 | |
| ++} Elf64_Vernaux;
 | |
| ++
 | |
| ++
 | |
| ++/* Legal values for vna_flags.  */
 | |
| ++#define VER_FLG_WEAK	0x2		/* Weak version identifier */
 | |
| ++
 | |
| ++
 | |
| ++/* Auxiliary vector.  */
 | |
| ++
 | |
| ++/* This vector is normally only used by the program interpreter.  The
 | |
| ++   usual definition in an ABI supplement uses the name auxv_t.  The
 | |
| ++   vector is not usually defined in a standard <elf.h> file, but it
 | |
| ++   can't hurt.  We rename it to avoid conflicts.  The sizes of these
 | |
| ++   types are an arrangement between the exec server and the program
 | |
| ++   interpreter, so we don't fully specify them here.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  uint32_t a_type;		/* Entry type */
 | |
| ++  union
 | |
| ++    {
 | |
| ++      uint32_t a_val;		/* Integer value */
 | |
| ++      /* We use to have pointer elements added here.  We cannot do that,
 | |
| ++	 though, since it does not work when using 32-bit definitions
 | |
| ++	 on 64-bit platforms and vice versa.  */
 | |
| ++    } a_un;
 | |
| ++} Elf32_auxv_t;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  uint64_t a_type;		/* Entry type */
 | |
| ++  union
 | |
| ++    {
 | |
| ++      uint64_t a_val;		/* Integer value */
 | |
| ++      /* We use to have pointer elements added here.  We cannot do that,
 | |
| ++	 though, since it does not work when using 32-bit definitions
 | |
| ++	 on 64-bit platforms and vice versa.  */
 | |
| ++    } a_un;
 | |
| ++} Elf64_auxv_t;
 | |
| ++
 | |
| ++/* Legal values for a_type (entry type).  */
 | |
| ++
 | |
| ++#define AT_NULL		0		/* End of vector */
 | |
| ++#define AT_IGNORE	1		/* Entry should be ignored */
 | |
| ++#define AT_EXECFD	2		/* File descriptor of program */
 | |
| ++#define AT_PHDR		3		/* Program headers for program */
 | |
| ++#define AT_PHENT	4		/* Size of program header entry */
 | |
| ++#define AT_PHNUM	5		/* Number of program headers */
 | |
| ++#define AT_PAGESZ	6		/* System page size */
 | |
| ++#define AT_BASE		7		/* Base address of interpreter */
 | |
| ++#define AT_FLAGS	8		/* Flags */
 | |
| ++#define AT_ENTRY	9		/* Entry point of program */
 | |
| ++#define AT_NOTELF	10		/* Program is not ELF */
 | |
| ++#define AT_UID		11		/* Real uid */
 | |
| ++#define AT_EUID		12		/* Effective uid */
 | |
| ++#define AT_GID		13		/* Real gid */
 | |
| ++#define AT_EGID		14		/* Effective gid */
 | |
| ++#define AT_CLKTCK	17		/* Frequency of times() */
 | |
| ++
 | |
| ++/* Some more special a_type values describing the hardware.  */
 | |
| ++#define AT_PLATFORM	15		/* String identifying platform.  */
 | |
| ++#define AT_HWCAP	16		/* Machine dependent hints about
 | |
| ++					   processor capabilities.  */
 | |
| ++
 | |
| ++/* This entry gives some information about the FPU initialization
 | |
| ++   performed by the kernel.  */
 | |
| ++#define AT_FPUCW	18		/* Used FPU control word.  */
 | |
| ++
 | |
| ++/* Cache block sizes.  */
 | |
| ++#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
 | |
| ++#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
 | |
| ++#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
 | |
| ++
 | |
| ++/* A special ignored value for PPC, used by the kernel to control the
 | |
| ++   interpretation of the AUXV. Must be > 16.  */
 | |
| ++#define AT_IGNOREPPC	22		/* Entry should be ignored.  */
 | |
| ++
 | |
| ++#define	AT_SECURE	23		/* Boolean, was exec setuid-like?  */
 | |
| ++
 | |
| ++#define AT_BASE_PLATFORM 24		/* String identifying real platforms.*/
 | |
| ++
 | |
| ++#define AT_RANDOM	25		/* Address of 16 random bytes.  */
 | |
| ++
 | |
| ++#define AT_EXECFN	31		/* Filename of executable.  */
 | |
| ++
 | |
| ++/* Pointer to the global system page used for system calls and other
 | |
| ++   nice things.  */
 | |
| ++#define AT_SYSINFO	32
 | |
| ++#define AT_SYSINFO_EHDR	33
 | |
| ++
 | |
| ++/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
 | |
| ++   log2 of line size; mask those to get cache size.  */
 | |
| ++#define AT_L1I_CACHESHAPE	34
 | |
| ++#define AT_L1D_CACHESHAPE	35
 | |
| ++#define AT_L2_CACHESHAPE	36
 | |
| ++#define AT_L3_CACHESHAPE	37
 | |
| ++
 | |
| ++/* Note section contents.  Each entry in the note section begins with
 | |
| ++   a header of a fixed form.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word n_namesz;			/* Length of the note's name.  */
 | |
| ++  Elf32_Word n_descsz;			/* Length of the note's descriptor.  */
 | |
| ++  Elf32_Word n_type;			/* Type of the note.  */
 | |
| ++} Elf32_Nhdr;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Word n_namesz;			/* Length of the note's name.  */
 | |
| ++  Elf64_Word n_descsz;			/* Length of the note's descriptor.  */
 | |
| ++  Elf64_Word n_type;			/* Type of the note.  */
 | |
| ++} Elf64_Nhdr;
 | |
| ++
 | |
| ++/* Known names of notes.  */
 | |
| ++
 | |
| ++/* Solaris entries in the note section have this name.  */
 | |
| ++#define ELF_NOTE_SOLARIS	"SUNW Solaris"
 | |
| ++
 | |
| ++/* Note entries for GNU systems have this name.  */
 | |
| ++#define ELF_NOTE_GNU		"GNU"
 | |
| ++
 | |
| ++
 | |
| ++/* Defined types of notes for Solaris.  */
 | |
| ++
 | |
| ++/* Value of descriptor (one word) is desired pagesize for the binary.  */
 | |
| ++#define ELF_NOTE_PAGESIZE_HINT	1
 | |
| ++
 | |
| ++
 | |
| ++/* Defined note types for GNU systems.  */
 | |
| ++
 | |
| ++/* ABI information.  The descriptor consists of words:
 | |
| ++   word 0: OS descriptor
 | |
| ++   word 1: major version of the ABI
 | |
| ++   word 2: minor version of the ABI
 | |
| ++   word 3: subminor version of the ABI
 | |
| ++*/
 | |
| ++#define NT_GNU_ABI_TAG	1
 | |
| ++#define ELF_NOTE_ABI	NT_GNU_ABI_TAG /* Old name.  */
 | |
| ++
 | |
| ++/* Known OSes.  These values can appear in word 0 of an
 | |
| ++   NT_GNU_ABI_TAG note section entry.  */
 | |
| ++#define ELF_NOTE_OS_LINUX	0
 | |
| ++#define ELF_NOTE_OS_GNU		1
 | |
| ++#define ELF_NOTE_OS_SOLARIS2	2
 | |
| ++#define ELF_NOTE_OS_FREEBSD	3
 | |
| ++
 | |
| ++/* Synthetic hwcap information.  The descriptor begins with two words:
 | |
| ++   word 0: number of entries
 | |
| ++   word 1: bitmask of enabled entries
 | |
| ++   Then follow variable-length entries, one byte followed by a
 | |
| ++   '\0'-terminated hwcap name string.  The byte gives the bit
 | |
| ++   number to test if enabled, (1U << bit) & bitmask.  */
 | |
| ++#define NT_GNU_HWCAP	2
 | |
| ++
 | |
| ++/* Build ID bits as generated by ld --build-id.
 | |
| ++   The descriptor consists of any nonzero number of bytes.  */
 | |
| ++#define NT_GNU_BUILD_ID	3
 | |
| ++
 | |
| ++/* Version note generated by GNU gold containing a version string.  */
 | |
| ++#define NT_GNU_GOLD_VERSION	4
 | |
| ++
 | |
| ++
 | |
| ++/* Move records.  */
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Xword m_value;		/* Symbol value.  */
 | |
| ++  Elf32_Word m_info;		/* Size and index.  */
 | |
| ++  Elf32_Word m_poffset;		/* Symbol offset.  */
 | |
| ++  Elf32_Half m_repeat;		/* Repeat count.  */
 | |
| ++  Elf32_Half m_stride;		/* Stride info.  */
 | |
| ++} Elf32_Move;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Xword m_value;		/* Symbol value.  */
 | |
| ++  Elf64_Xword m_info;		/* Size and index.  */
 | |
| ++  Elf64_Xword m_poffset;	/* Symbol offset.  */
 | |
| ++  Elf64_Half m_repeat;		/* Repeat count.  */
 | |
| ++  Elf64_Half m_stride;		/* Stride info.  */
 | |
| ++} Elf64_Move;
 | |
| ++
 | |
| ++/* Macro to construct move records.  */
 | |
| ++#define ELF32_M_SYM(info)	((info) >> 8)
 | |
| ++#define ELF32_M_SIZE(info)	((unsigned char) (info))
 | |
| ++#define ELF32_M_INFO(sym, size)	(((sym) << 8) + (unsigned char) (size))
 | |
| ++
 | |
| ++#define ELF64_M_SYM(info)	ELF32_M_SYM (info)
 | |
| ++#define ELF64_M_SIZE(info)	ELF32_M_SIZE (info)
 | |
| ++#define ELF64_M_INFO(sym, size)	ELF32_M_INFO (sym, size)
 | |
| ++
 | |
| ++
 | |
| ++/* Motorola 68k specific definitions.  */
 | |
| ++
 | |
| ++/* Values for Elf32_Ehdr.e_flags.  */
 | |
| ++#define EF_CPU32	0x00810000
 | |
| ++
 | |
| ++/* m68k relocs.  */
 | |
| ++
 | |
| ++#define R_68K_NONE	0		/* No reloc */
 | |
| ++#define R_68K_32	1		/* Direct 32 bit  */
 | |
| ++#define R_68K_16	2		/* Direct 16 bit  */
 | |
| ++#define R_68K_8		3		/* Direct 8 bit  */
 | |
| ++#define R_68K_PC32	4		/* PC relative 32 bit */
 | |
| ++#define R_68K_PC16	5		/* PC relative 16 bit */
 | |
| ++#define R_68K_PC8	6		/* PC relative 8 bit */
 | |
| ++#define R_68K_GOT32	7		/* 32 bit PC relative GOT entry */
 | |
| ++#define R_68K_GOT16	8		/* 16 bit PC relative GOT entry */
 | |
| ++#define R_68K_GOT8	9		/* 8 bit PC relative GOT entry */
 | |
| ++#define R_68K_GOT32O	10		/* 32 bit GOT offset */
 | |
| ++#define R_68K_GOT16O	11		/* 16 bit GOT offset */
 | |
| ++#define R_68K_GOT8O	12		/* 8 bit GOT offset */
 | |
| ++#define R_68K_PLT32	13		/* 32 bit PC relative PLT address */
 | |
| ++#define R_68K_PLT16	14		/* 16 bit PC relative PLT address */
 | |
| ++#define R_68K_PLT8	15		/* 8 bit PC relative PLT address */
 | |
| ++#define R_68K_PLT32O	16		/* 32 bit PLT offset */
 | |
| ++#define R_68K_PLT16O	17		/* 16 bit PLT offset */
 | |
| ++#define R_68K_PLT8O	18		/* 8 bit PLT offset */
 | |
| ++#define R_68K_COPY	19		/* Copy symbol at runtime */
 | |
| ++#define R_68K_GLOB_DAT	20		/* Create GOT entry */
 | |
| ++#define R_68K_JMP_SLOT	21		/* Create PLT entry */
 | |
| ++#define R_68K_RELATIVE	22		/* Adjust by program base */
 | |
| ++#define R_68K_TLS_GD32      25          /* 32 bit GOT offset for GD */
 | |
| ++#define R_68K_TLS_GD16      26          /* 16 bit GOT offset for GD */
 | |
| ++#define R_68K_TLS_GD8       27          /* 8 bit GOT offset for GD */
 | |
| ++#define R_68K_TLS_LDM32     28          /* 32 bit GOT offset for LDM */
 | |
| ++#define R_68K_TLS_LDM16     29          /* 16 bit GOT offset for LDM */
 | |
| ++#define R_68K_TLS_LDM8      30          /* 8 bit GOT offset for LDM */
 | |
| ++#define R_68K_TLS_LDO32     31          /* 32 bit module-relative offset */
 | |
| ++#define R_68K_TLS_LDO16     32          /* 16 bit module-relative offset */
 | |
| ++#define R_68K_TLS_LDO8      33          /* 8 bit module-relative offset */
 | |
| ++#define R_68K_TLS_IE32      34          /* 32 bit GOT offset for IE */
 | |
| ++#define R_68K_TLS_IE16      35          /* 16 bit GOT offset for IE */
 | |
| ++#define R_68K_TLS_IE8       36          /* 8 bit GOT offset for IE */
 | |
| ++#define R_68K_TLS_LE32      37          /* 32 bit offset relative to
 | |
| ++					   static TLS block */
 | |
| ++#define R_68K_TLS_LE16      38          /* 16 bit offset relative to
 | |
| ++					   static TLS block */
 | |
| ++#define R_68K_TLS_LE8       39          /* 8 bit offset relative to
 | |
| ++					   static TLS block */
 | |
| ++#define R_68K_TLS_DTPMOD32  40          /* 32 bit module number */
 | |
| ++#define R_68K_TLS_DTPREL32  41          /* 32 bit module-relative offset */
 | |
| ++#define R_68K_TLS_TPREL32   42          /* 32 bit TP-relative offset */
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define R_68K_NUM	43
 | |
| ++
 | |
| ++/* Intel 80386 specific definitions.  */
 | |
| ++
 | |
| ++/* i386 relocs.  */
 | |
| ++
 | |
| ++#define R_386_NONE	   0		/* No reloc */
 | |
| ++#define R_386_32	   1		/* Direct 32 bit  */
 | |
| ++#define R_386_PC32	   2		/* PC relative 32 bit */
 | |
| ++#define R_386_GOT32	   3		/* 32 bit GOT entry */
 | |
| ++#define R_386_PLT32	   4		/* 32 bit PLT address */
 | |
| ++#define R_386_COPY	   5		/* Copy symbol at runtime */
 | |
| ++#define R_386_GLOB_DAT	   6		/* Create GOT entry */
 | |
| ++#define R_386_JMP_SLOT	   7		/* Create PLT entry */
 | |
| ++#define R_386_RELATIVE	   8		/* Adjust by program base */
 | |
| ++#define R_386_GOTOFF	   9		/* 32 bit offset to GOT */
 | |
| ++#define R_386_GOTPC	   10		/* 32 bit PC relative offset to GOT */
 | |
| ++#define R_386_32PLT	   11
 | |
| ++#define R_386_TLS_TPOFF	   14		/* Offset in static TLS block */
 | |
| ++#define R_386_TLS_IE	   15		/* Address of GOT entry for static TLS
 | |
| ++					   block offset */
 | |
| ++#define R_386_TLS_GOTIE	   16		/* GOT entry for static TLS block
 | |
| ++					   offset */
 | |
| ++#define R_386_TLS_LE	   17		/* Offset relative to static TLS
 | |
| ++					   block */
 | |
| ++#define R_386_TLS_GD	   18		/* Direct 32 bit for GNU version of
 | |
| ++					   general dynamic thread local data */
 | |
| ++#define R_386_TLS_LDM	   19		/* Direct 32 bit for GNU version of
 | |
| ++					   local dynamic thread local data
 | |
| ++					   in LE code */
 | |
| ++#define R_386_16	   20
 | |
| ++#define R_386_PC16	   21
 | |
| ++#define R_386_8		   22
 | |
| ++#define R_386_PC8	   23
 | |
| ++#define R_386_TLS_GD_32	   24		/* Direct 32 bit for general dynamic
 | |
| ++					   thread local data */
 | |
| ++#define R_386_TLS_GD_PUSH  25		/* Tag for pushl in GD TLS code */
 | |
| ++#define R_386_TLS_GD_CALL  26		/* Relocation for call to
 | |
| ++					   __tls_get_addr() */
 | |
| ++#define R_386_TLS_GD_POP   27		/* Tag for popl in GD TLS code */
 | |
| ++#define R_386_TLS_LDM_32   28		/* Direct 32 bit for local dynamic
 | |
| ++					   thread local data in LE code */
 | |
| ++#define R_386_TLS_LDM_PUSH 29		/* Tag for pushl in LDM TLS code */
 | |
| ++#define R_386_TLS_LDM_CALL 30		/* Relocation for call to
 | |
| ++					   __tls_get_addr() in LDM code */
 | |
| ++#define R_386_TLS_LDM_POP  31		/* Tag for popl in LDM TLS code */
 | |
| ++#define R_386_TLS_LDO_32   32		/* Offset relative to TLS block */
 | |
| ++#define R_386_TLS_IE_32	   33		/* GOT entry for negated static TLS
 | |
| ++					   block offset */
 | |
| ++#define R_386_TLS_LE_32	   34		/* Negated offset relative to static
 | |
| ++					   TLS block */
 | |
| ++#define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
 | |
| ++#define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
 | |
| ++#define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
 | |
| ++/* 38? */
 | |
| ++#define R_386_TLS_GOTDESC  39		/* GOT offset for TLS descriptor.  */
 | |
| ++#define R_386_TLS_DESC_CALL 40		/* Marker of call through TLS
 | |
| ++					   descriptor for
 | |
| ++					   relaxation.  */
 | |
| ++#define R_386_TLS_DESC     41		/* TLS descriptor containing
 | |
| ++					   pointer to code and to
 | |
| ++					   argument, returning the TLS
 | |
| ++					   offset for the symbol.  */
 | |
| ++#define R_386_IRELATIVE	   42		/* Adjust indirectly by program base */
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define R_386_NUM	   43
 | |
| ++
 | |
| ++/* SUN SPARC specific definitions.  */
 | |
| ++
 | |
| ++/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
 | |
| ++
 | |
| ++#define STT_SPARC_REGISTER	13	/* Global register reserved to app. */
 | |
| ++
 | |
| ++/* Values for Elf64_Ehdr.e_flags.  */
 | |
| ++
 | |
| ++#define EF_SPARCV9_MM		3
 | |
| ++#define EF_SPARCV9_TSO		0
 | |
| ++#define EF_SPARCV9_PSO		1
 | |
| ++#define EF_SPARCV9_RMO		2
 | |
| ++#define EF_SPARC_LEDATA		0x800000 /* little endian data */
 | |
| ++#define EF_SPARC_EXT_MASK	0xFFFF00
 | |
| ++#define EF_SPARC_32PLUS		0x000100 /* generic V8+ features */
 | |
| ++#define EF_SPARC_SUN_US1	0x000200 /* Sun UltraSPARC1 extensions */
 | |
| ++#define EF_SPARC_HAL_R1		0x000400 /* HAL R1 extensions */
 | |
| ++#define EF_SPARC_SUN_US3	0x000800 /* Sun UltraSPARCIII extensions */
 | |
| ++
 | |
| ++/* SPARC relocs.  */
 | |
| ++
 | |
| ++#define R_SPARC_NONE		0	/* No reloc */
 | |
| ++#define R_SPARC_8		1	/* Direct 8 bit */
 | |
| ++#define R_SPARC_16		2	/* Direct 16 bit */
 | |
| ++#define R_SPARC_32		3	/* Direct 32 bit */
 | |
| ++#define R_SPARC_DISP8		4	/* PC relative 8 bit */
 | |
| ++#define R_SPARC_DISP16		5	/* PC relative 16 bit */
 | |
| ++#define R_SPARC_DISP32		6	/* PC relative 32 bit */
 | |
| ++#define R_SPARC_WDISP30		7	/* PC relative 30 bit shifted */
 | |
| ++#define R_SPARC_WDISP22		8	/* PC relative 22 bit shifted */
 | |
| ++#define R_SPARC_HI22		9	/* High 22 bit */
 | |
| ++#define R_SPARC_22		10	/* Direct 22 bit */
 | |
| ++#define R_SPARC_13		11	/* Direct 13 bit */
 | |
| ++#define R_SPARC_LO10		12	/* Truncated 10 bit */
 | |
| ++#define R_SPARC_GOT10		13	/* Truncated 10 bit GOT entry */
 | |
| ++#define R_SPARC_GOT13		14	/* 13 bit GOT entry */
 | |
| ++#define R_SPARC_GOT22		15	/* 22 bit GOT entry shifted */
 | |
| ++#define R_SPARC_PC10		16	/* PC relative 10 bit truncated */
 | |
| ++#define R_SPARC_PC22		17	/* PC relative 22 bit shifted */
 | |
| ++#define R_SPARC_WPLT30		18	/* 30 bit PC relative PLT address */
 | |
| ++#define R_SPARC_COPY		19	/* Copy symbol at runtime */
 | |
| ++#define R_SPARC_GLOB_DAT	20	/* Create GOT entry */
 | |
| ++#define R_SPARC_JMP_SLOT	21	/* Create PLT entry */
 | |
| ++#define R_SPARC_RELATIVE	22	/* Adjust by program base */
 | |
| ++#define R_SPARC_UA32		23	/* Direct 32 bit unaligned */
 | |
| ++
 | |
| ++/* Additional Sparc64 relocs.  */
 | |
| ++
 | |
| ++#define R_SPARC_PLT32		24	/* Direct 32 bit ref to PLT entry */
 | |
| ++#define R_SPARC_HIPLT22		25	/* High 22 bit PLT entry */
 | |
| ++#define R_SPARC_LOPLT10		26	/* Truncated 10 bit PLT entry */
 | |
| ++#define R_SPARC_PCPLT32		27	/* PC rel 32 bit ref to PLT entry */
 | |
| ++#define R_SPARC_PCPLT22		28	/* PC rel high 22 bit PLT entry */
 | |
| ++#define R_SPARC_PCPLT10		29	/* PC rel trunc 10 bit PLT entry */
 | |
| ++#define R_SPARC_10		30	/* Direct 10 bit */
 | |
| ++#define R_SPARC_11		31	/* Direct 11 bit */
 | |
| ++#define R_SPARC_64		32	/* Direct 64 bit */
 | |
| ++#define R_SPARC_OLO10		33	/* 10bit with secondary 13bit addend */
 | |
| ++#define R_SPARC_HH22		34	/* Top 22 bits of direct 64 bit */
 | |
| ++#define R_SPARC_HM10		35	/* High middle 10 bits of ... */
 | |
| ++#define R_SPARC_LM22		36	/* Low middle 22 bits of ... */
 | |
| ++#define R_SPARC_PC_HH22		37	/* Top 22 bits of pc rel 64 bit */
 | |
| ++#define R_SPARC_PC_HM10		38	/* High middle 10 bit of ... */
 | |
| ++#define R_SPARC_PC_LM22		39	/* Low miggle 22 bits of ... */
 | |
| ++#define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
 | |
| ++#define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
 | |
| ++#define R_SPARC_GLOB_JMP	42	/* was part of v9 ABI but was removed */
 | |
| ++#define R_SPARC_7		43	/* Direct 7 bit */
 | |
| ++#define R_SPARC_5		44	/* Direct 5 bit */
 | |
| ++#define R_SPARC_6		45	/* Direct 6 bit */
 | |
| ++#define R_SPARC_DISP64		46	/* PC relative 64 bit */
 | |
| ++#define R_SPARC_PLT64		47	/* Direct 64 bit ref to PLT entry */
 | |
| ++#define R_SPARC_HIX22		48	/* High 22 bit complemented */
 | |
| ++#define R_SPARC_LOX10		49	/* Truncated 11 bit complemented */
 | |
| ++#define R_SPARC_H44		50	/* Direct high 12 of 44 bit */
 | |
| ++#define R_SPARC_M44		51	/* Direct mid 22 of 44 bit */
 | |
| ++#define R_SPARC_L44		52	/* Direct low 10 of 44 bit */
 | |
| ++#define R_SPARC_REGISTER	53	/* Global register usage */
 | |
| ++#define R_SPARC_UA64		54	/* Direct 64 bit unaligned */
 | |
| ++#define R_SPARC_UA16		55	/* Direct 16 bit unaligned */
 | |
| ++#define R_SPARC_TLS_GD_HI22	56
 | |
| ++#define R_SPARC_TLS_GD_LO10	57
 | |
| ++#define R_SPARC_TLS_GD_ADD	58
 | |
| ++#define R_SPARC_TLS_GD_CALL	59
 | |
| ++#define R_SPARC_TLS_LDM_HI22	60
 | |
| ++#define R_SPARC_TLS_LDM_LO10	61
 | |
| ++#define R_SPARC_TLS_LDM_ADD	62
 | |
| ++#define R_SPARC_TLS_LDM_CALL	63
 | |
| ++#define R_SPARC_TLS_LDO_HIX22	64
 | |
| ++#define R_SPARC_TLS_LDO_LOX10	65
 | |
| ++#define R_SPARC_TLS_LDO_ADD	66
 | |
| ++#define R_SPARC_TLS_IE_HI22	67
 | |
| ++#define R_SPARC_TLS_IE_LO10	68
 | |
| ++#define R_SPARC_TLS_IE_LD	69
 | |
| ++#define R_SPARC_TLS_IE_LDX	70
 | |
| ++#define R_SPARC_TLS_IE_ADD	71
 | |
| ++#define R_SPARC_TLS_LE_HIX22	72
 | |
| ++#define R_SPARC_TLS_LE_LOX10	73
 | |
| ++#define R_SPARC_TLS_DTPMOD32	74
 | |
| ++#define R_SPARC_TLS_DTPMOD64	75
 | |
| ++#define R_SPARC_TLS_DTPOFF32	76
 | |
| ++#define R_SPARC_TLS_DTPOFF64	77
 | |
| ++#define R_SPARC_TLS_TPOFF32	78
 | |
| ++#define R_SPARC_TLS_TPOFF64	79
 | |
| ++#define R_SPARC_GOTDATA_HIX22	80
 | |
| ++#define R_SPARC_GOTDATA_LOX10	81
 | |
| ++#define R_SPARC_GOTDATA_OP_HIX22	82
 | |
| ++#define R_SPARC_GOTDATA_OP_LOX10	83
 | |
| ++#define R_SPARC_GOTDATA_OP	84
 | |
| ++#define R_SPARC_H34		85
 | |
| ++#define R_SPARC_SIZE32		86
 | |
| ++#define R_SPARC_SIZE64		87
 | |
| ++#define R_SPARC_WDISP10		88
 | |
| ++#define R_SPARC_JMP_IREL	248
 | |
| ++#define R_SPARC_IRELATIVE	249
 | |
| ++#define R_SPARC_GNU_VTINHERIT	250
 | |
| ++#define R_SPARC_GNU_VTENTRY	251
 | |
| ++#define R_SPARC_REV32		252
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define R_SPARC_NUM		253
 | |
| ++
 | |
| ++/* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
 | |
| ++
 | |
| ++#define DT_SPARC_REGISTER 0x70000001
 | |
| ++#define DT_SPARC_NUM	2
 | |
| ++
 | |
| ++/* MIPS R3000 specific definitions.  */
 | |
| ++
 | |
| ++/* Legal values for e_flags field of Elf32_Ehdr.  */
 | |
| ++
 | |
| ++#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
 | |
| ++#define EF_MIPS_PIC	    2		/* Contains PIC code */
 | |
| ++#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
 | |
| ++#define EF_MIPS_XGOT	    8
 | |
| ++#define EF_MIPS_64BIT_WHIRL 16
 | |
| ++#define EF_MIPS_ABI2	    32
 | |
| ++#define EF_MIPS_ABI_ON32    64
 | |
| ++#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
 | |
| ++
 | |
| ++/* Legal values for MIPS architecture level.  */
 | |
| ++
 | |
| ++#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
 | |
| ++#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
 | |
| ++#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
 | |
| ++#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
 | |
| ++#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
 | |
| ++#define EF_MIPS_ARCH_32	    0x60000000	/* MIPS32 code.  */
 | |
| ++#define EF_MIPS_ARCH_64	    0x70000000	/* MIPS64 code.  */
 | |
| ++
 | |
| ++/* The following are non-official names and should not be used.  */
 | |
| ++
 | |
| ++#define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
 | |
| ++#define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
 | |
| ++#define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
 | |
| ++#define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
 | |
| ++#define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
 | |
| ++#define E_MIPS_ARCH_32	  0x60000000	/* MIPS32 code.  */
 | |
| ++#define E_MIPS_ARCH_64	  0x70000000	/* MIPS64 code.  */
 | |
| ++
 | |
| ++/* Special section indices.  */
 | |
| ++
 | |
| ++#define SHN_MIPS_ACOMMON    0xff00	/* Allocated common symbols */
 | |
| ++#define SHN_MIPS_TEXT	    0xff01	/* Allocated test symbols.  */
 | |
| ++#define SHN_MIPS_DATA	    0xff02	/* Allocated data symbols.  */
 | |
| ++#define SHN_MIPS_SCOMMON    0xff03	/* Small common symbols */
 | |
| ++#define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
 | |
| ++
 | |
| ++/* Legal values for sh_type field of Elf32_Shdr.  */
 | |
| ++
 | |
| ++#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
 | |
| ++#define SHT_MIPS_MSYM	       0x70000001
 | |
| ++#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
 | |
| ++#define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
 | |
| ++#define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
 | |
| ++#define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
 | |
| ++#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
 | |
| ++#define SHT_MIPS_PACKAGE       0x70000007
 | |
| ++#define SHT_MIPS_PACKSYM       0x70000008
 | |
| ++#define SHT_MIPS_RELD	       0x70000009
 | |
| ++#define SHT_MIPS_IFACE         0x7000000b
 | |
| ++#define SHT_MIPS_CONTENT       0x7000000c
 | |
| ++#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
 | |
| ++#define SHT_MIPS_SHDR	       0x70000010
 | |
| ++#define SHT_MIPS_FDESC	       0x70000011
 | |
| ++#define SHT_MIPS_EXTSYM	       0x70000012
 | |
| ++#define SHT_MIPS_DENSE	       0x70000013
 | |
| ++#define SHT_MIPS_PDESC	       0x70000014
 | |
| ++#define SHT_MIPS_LOCSYM	       0x70000015
 | |
| ++#define SHT_MIPS_AUXSYM	       0x70000016
 | |
| ++#define SHT_MIPS_OPTSYM	       0x70000017
 | |
| ++#define SHT_MIPS_LOCSTR	       0x70000018
 | |
| ++#define SHT_MIPS_LINE	       0x70000019
 | |
| ++#define SHT_MIPS_RFDESC	       0x7000001a
 | |
| ++#define SHT_MIPS_DELTASYM      0x7000001b
 | |
| ++#define SHT_MIPS_DELTAINST     0x7000001c
 | |
| ++#define SHT_MIPS_DELTACLASS    0x7000001d
 | |
| ++#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
 | |
| ++#define SHT_MIPS_DELTADECL     0x7000001f
 | |
| ++#define SHT_MIPS_SYMBOL_LIB    0x70000020
 | |
| ++#define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
 | |
| ++#define SHT_MIPS_TRANSLATE     0x70000022
 | |
| ++#define SHT_MIPS_PIXIE	       0x70000023
 | |
| ++#define SHT_MIPS_XLATE	       0x70000024
 | |
| ++#define SHT_MIPS_XLATE_DEBUG   0x70000025
 | |
| ++#define SHT_MIPS_WHIRL	       0x70000026
 | |
| ++#define SHT_MIPS_EH_REGION     0x70000027
 | |
| ++#define SHT_MIPS_XLATE_OLD     0x70000028
 | |
| ++#define SHT_MIPS_PDR_EXCEPTION 0x70000029
 | |
| ++
 | |
| ++/* Legal values for sh_flags field of Elf32_Shdr.  */
 | |
| ++
 | |
| ++#define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
 | |
| ++#define SHF_MIPS_MERGE	 0x20000000
 | |
| ++#define SHF_MIPS_ADDR	 0x40000000
 | |
| ++#define SHF_MIPS_STRINGS 0x80000000
 | |
| ++#define SHF_MIPS_NOSTRIP 0x08000000
 | |
| ++#define SHF_MIPS_LOCAL	 0x04000000
 | |
| ++#define SHF_MIPS_NAMES	 0x02000000
 | |
| ++#define SHF_MIPS_NODUPE	 0x01000000
 | |
| ++
 | |
| ++
 | |
| ++/* Symbol tables.  */
 | |
| ++
 | |
| ++/* MIPS specific values for `st_other'.  */
 | |
| ++#define STO_MIPS_DEFAULT		0x0
 | |
| ++#define STO_MIPS_INTERNAL		0x1
 | |
| ++#define STO_MIPS_HIDDEN			0x2
 | |
| ++#define STO_MIPS_PROTECTED		0x3
 | |
| ++#define STO_MIPS_PLT			0x8
 | |
| ++#define STO_MIPS_SC_ALIGN_UNUSED	0xff
 | |
| ++
 | |
| ++/* MIPS specific values for `st_info'.  */
 | |
| ++#define STB_MIPS_SPLIT_COMMON		13
 | |
| ++
 | |
| ++/* Entries found in sections of type SHT_MIPS_GPTAB.  */
 | |
| ++
 | |
| ++typedef union
 | |
| ++{
 | |
| ++  struct
 | |
| ++    {
 | |
| ++      Elf32_Word gt_current_g_value;	/* -G value used for compilation */
 | |
| ++      Elf32_Word gt_unused;		/* Not used */
 | |
| ++    } gt_header;			/* First entry in section */
 | |
| ++  struct
 | |
| ++    {
 | |
| ++      Elf32_Word gt_g_value;		/* If this value were used for -G */
 | |
| ++      Elf32_Word gt_bytes;		/* This many bytes would be used */
 | |
| ++    } gt_entry;				/* Subsequent entries in section */
 | |
| ++} Elf32_gptab;
 | |
| ++
 | |
| ++/* Entry found in sections of type SHT_MIPS_REGINFO.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word	ri_gprmask;		/* General registers used */
 | |
| ++  Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
 | |
| ++  Elf32_Sword	ri_gp_value;		/* $gp register value */
 | |
| ++} Elf32_RegInfo;
 | |
| ++
 | |
| ++/* Entries found in sections of type SHT_MIPS_OPTIONS.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  unsigned char kind;		/* Determines interpretation of the
 | |
| ++				   variable part of descriptor.  */
 | |
| ++  unsigned char size;		/* Size of descriptor, including header.  */
 | |
| ++  Elf32_Section section;	/* Section header index of section affected,
 | |
| ++				   0 for global options.  */
 | |
| ++  Elf32_Word info;		/* Kind-specific information.  */
 | |
| ++} Elf_Options;
 | |
| ++
 | |
| ++/* Values for `kind' field in Elf_Options.  */
 | |
| ++
 | |
| ++#define ODK_NULL	0	/* Undefined.  */
 | |
| ++#define ODK_REGINFO	1	/* Register usage information.  */
 | |
| ++#define ODK_EXCEPTIONS	2	/* Exception processing options.  */
 | |
| ++#define ODK_PAD		3	/* Section padding options.  */
 | |
| ++#define ODK_HWPATCH	4	/* Hardware workarounds performed */
 | |
| ++#define ODK_FILL	5	/* record the fill value used by the linker. */
 | |
| ++#define ODK_TAGS	6	/* reserve space for desktop tools to write. */
 | |
| ++#define ODK_HWAND	7	/* HW workarounds.  'AND' bits when merging. */
 | |
| ++#define ODK_HWOR	8	/* HW workarounds.  'OR' bits when merging.  */
 | |
| ++
 | |
| ++/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries.  */
 | |
| ++
 | |
| ++#define OEX_FPU_MIN	0x1f	/* FPE's which MUST be enabled.  */
 | |
| ++#define OEX_FPU_MAX	0x1f00	/* FPE's which MAY be enabled.  */
 | |
| ++#define OEX_PAGE0	0x10000	/* page zero must be mapped.  */
 | |
| ++#define OEX_SMM		0x20000	/* Force sequential memory mode?  */
 | |
| ++#define OEX_FPDBUG	0x40000	/* Force floating point debug mode?  */
 | |
| ++#define OEX_PRECISEFP	OEX_FPDBUG
 | |
| ++#define OEX_DISMISS	0x80000	/* Dismiss invalid address faults?  */
 | |
| ++
 | |
| ++#define OEX_FPU_INVAL	0x10
 | |
| ++#define OEX_FPU_DIV0	0x08
 | |
| ++#define OEX_FPU_OFLO	0x04
 | |
| ++#define OEX_FPU_UFLO	0x02
 | |
| ++#define OEX_FPU_INEX	0x01
 | |
| ++
 | |
| ++/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry.  */
 | |
| ++
 | |
| ++#define OHW_R4KEOP	0x1	/* R4000 end-of-page patch.  */
 | |
| ++#define OHW_R8KPFETCH	0x2	/* may need R8000 prefetch patch.  */
 | |
| ++#define OHW_R5KEOP	0x4	/* R5000 end-of-page patch.  */
 | |
| ++#define OHW_R5KCVTL	0x8	/* R5000 cvt.[ds].l bug.  clean=1.  */
 | |
| ++
 | |
| ++#define OPAD_PREFIX	0x1
 | |
| ++#define OPAD_POSTFIX	0x2
 | |
| ++#define OPAD_SYMBOL	0x4
 | |
| ++
 | |
| ++/* Entry found in `.options' section.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word hwp_flags1;	/* Extra flags.  */
 | |
| ++  Elf32_Word hwp_flags2;	/* Extra flags.  */
 | |
| ++} Elf_Options_Hw;
 | |
| ++
 | |
| ++/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries.  */
 | |
| ++
 | |
| ++#define OHWA0_R4KEOP_CHECKED	0x00000001
 | |
| ++#define OHWA1_R4KEOP_CLEAN	0x00000002
 | |
| ++
 | |
| ++/* MIPS relocs.  */
 | |
| ++
 | |
| ++#define R_MIPS_NONE		0	/* No reloc */
 | |
| ++#define R_MIPS_16		1	/* Direct 16 bit */
 | |
| ++#define R_MIPS_32		2	/* Direct 32 bit */
 | |
| ++#define R_MIPS_REL32		3	/* PC relative 32 bit */
 | |
| ++#define R_MIPS_26		4	/* Direct 26 bit shifted */
 | |
| ++#define R_MIPS_HI16		5	/* High 16 bit */
 | |
| ++#define R_MIPS_LO16		6	/* Low 16 bit */
 | |
| ++#define R_MIPS_GPREL16		7	/* GP relative 16 bit */
 | |
| ++#define R_MIPS_LITERAL		8	/* 16 bit literal entry */
 | |
| ++#define R_MIPS_GOT16		9	/* 16 bit GOT entry */
 | |
| ++#define R_MIPS_PC16		10	/* PC relative 16 bit */
 | |
| ++#define R_MIPS_CALL16		11	/* 16 bit GOT entry for function */
 | |
| ++#define R_MIPS_GPREL32		12	/* GP relative 32 bit */
 | |
| ++
 | |
| ++#define R_MIPS_SHIFT5		16
 | |
| ++#define R_MIPS_SHIFT6		17
 | |
| ++#define R_MIPS_64		18
 | |
| ++#define R_MIPS_GOT_DISP		19
 | |
| ++#define R_MIPS_GOT_PAGE		20
 | |
| ++#define R_MIPS_GOT_OFST		21
 | |
| ++#define R_MIPS_GOT_HI16		22
 | |
| ++#define R_MIPS_GOT_LO16		23
 | |
| ++#define R_MIPS_SUB		24
 | |
| ++#define R_MIPS_INSERT_A		25
 | |
| ++#define R_MIPS_INSERT_B		26
 | |
| ++#define R_MIPS_DELETE		27
 | |
| ++#define R_MIPS_HIGHER		28
 | |
| ++#define R_MIPS_HIGHEST		29
 | |
| ++#define R_MIPS_CALL_HI16	30
 | |
| ++#define R_MIPS_CALL_LO16	31
 | |
| ++#define R_MIPS_SCN_DISP		32
 | |
| ++#define R_MIPS_REL16		33
 | |
| ++#define R_MIPS_ADD_IMMEDIATE	34
 | |
| ++#define R_MIPS_PJUMP		35
 | |
| ++#define R_MIPS_RELGOT		36
 | |
| ++#define R_MIPS_JALR		37
 | |
| ++#define R_MIPS_TLS_DTPMOD32	38	/* Module number 32 bit */
 | |
| ++#define R_MIPS_TLS_DTPREL32	39	/* Module-relative offset 32 bit */
 | |
| ++#define R_MIPS_TLS_DTPMOD64	40	/* Module number 64 bit */
 | |
| ++#define R_MIPS_TLS_DTPREL64	41	/* Module-relative offset 64 bit */
 | |
| ++#define R_MIPS_TLS_GD		42	/* 16 bit GOT offset for GD */
 | |
| ++#define R_MIPS_TLS_LDM		43	/* 16 bit GOT offset for LDM */
 | |
| ++#define R_MIPS_TLS_DTPREL_HI16	44	/* Module-relative offset, high 16 bits */
 | |
| ++#define R_MIPS_TLS_DTPREL_LO16	45	/* Module-relative offset, low 16 bits */
 | |
| ++#define R_MIPS_TLS_GOTTPREL	46	/* 16 bit GOT offset for IE */
 | |
| ++#define R_MIPS_TLS_TPREL32	47	/* TP-relative offset, 32 bit */
 | |
| ++#define R_MIPS_TLS_TPREL64	48	/* TP-relative offset, 64 bit */
 | |
| ++#define R_MIPS_TLS_TPREL_HI16	49	/* TP-relative offset, high 16 bits */
 | |
| ++#define R_MIPS_TLS_TPREL_LO16	50	/* TP-relative offset, low 16 bits */
 | |
| ++#define R_MIPS_GLOB_DAT		51
 | |
| ++#define R_MIPS_COPY		126
 | |
| ++#define R_MIPS_JUMP_SLOT        127
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define R_MIPS_NUM		128
 | |
| ++
 | |
| ++/* Legal values for p_type field of Elf32_Phdr.  */
 | |
| ++
 | |
| ++#define PT_MIPS_REGINFO	0x70000000	/* Register usage information */
 | |
| ++#define PT_MIPS_RTPROC  0x70000001	/* Runtime procedure table. */
 | |
| ++#define PT_MIPS_OPTIONS 0x70000002
 | |
| ++
 | |
| ++/* Special program header types.  */
 | |
| ++
 | |
| ++#define PF_MIPS_LOCAL	0x10000000
 | |
| ++
 | |
| ++/* Legal values for d_tag field of Elf32_Dyn.  */
 | |
| ++
 | |
| ++#define DT_MIPS_RLD_VERSION  0x70000001	/* Runtime linker interface version */
 | |
| ++#define DT_MIPS_TIME_STAMP   0x70000002	/* Timestamp */
 | |
| ++#define DT_MIPS_ICHECKSUM    0x70000003	/* Checksum */
 | |
| ++#define DT_MIPS_IVERSION     0x70000004	/* Version string (string tbl index) */
 | |
| ++#define DT_MIPS_FLAGS	     0x70000005	/* Flags */
 | |
| ++#define DT_MIPS_BASE_ADDRESS 0x70000006	/* Base address */
 | |
| ++#define DT_MIPS_MSYM	     0x70000007
 | |
| ++#define DT_MIPS_CONFLICT     0x70000008	/* Address of CONFLICT section */
 | |
| ++#define DT_MIPS_LIBLIST	     0x70000009	/* Address of LIBLIST section */
 | |
| ++#define DT_MIPS_LOCAL_GOTNO  0x7000000a	/* Number of local GOT entries */
 | |
| ++#define DT_MIPS_CONFLICTNO   0x7000000b	/* Number of CONFLICT entries */
 | |
| ++#define DT_MIPS_LIBLISTNO    0x70000010	/* Number of LIBLIST entries */
 | |
| ++#define DT_MIPS_SYMTABNO     0x70000011	/* Number of DYNSYM entries */
 | |
| ++#define DT_MIPS_UNREFEXTNO   0x70000012	/* First external DYNSYM */
 | |
| ++#define DT_MIPS_GOTSYM	     0x70000013	/* First GOT entry in DYNSYM */
 | |
| ++#define DT_MIPS_HIPAGENO     0x70000014	/* Number of GOT page table entries */
 | |
| ++#define DT_MIPS_RLD_MAP	     0x70000016	/* Address of run time loader map.  */
 | |
| ++#define DT_MIPS_DELTA_CLASS  0x70000017	/* Delta C++ class definition.  */
 | |
| ++#define DT_MIPS_DELTA_CLASS_NO    0x70000018 /* Number of entries in
 | |
| ++						DT_MIPS_DELTA_CLASS.  */
 | |
| ++#define DT_MIPS_DELTA_INSTANCE    0x70000019 /* Delta C++ class instances.  */
 | |
| ++#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
 | |
| ++						DT_MIPS_DELTA_INSTANCE.  */
 | |
| ++#define DT_MIPS_DELTA_RELOC  0x7000001b /* Delta relocations.  */
 | |
| ++#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
 | |
| ++					     DT_MIPS_DELTA_RELOC.  */
 | |
| ++#define DT_MIPS_DELTA_SYM    0x7000001d /* Delta symbols that Delta
 | |
| ++					   relocations refer to.  */
 | |
| ++#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
 | |
| ++					   DT_MIPS_DELTA_SYM.  */
 | |
| ++#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
 | |
| ++					     class declaration.  */
 | |
| ++#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
 | |
| ++						DT_MIPS_DELTA_CLASSSYM.  */
 | |
| ++#define DT_MIPS_CXX_FLAGS    0x70000022 /* Flags indicating for C++ flavor.  */
 | |
| ++#define DT_MIPS_PIXIE_INIT   0x70000023
 | |
| ++#define DT_MIPS_SYMBOL_LIB   0x70000024
 | |
| ++#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
 | |
| ++#define DT_MIPS_LOCAL_GOTIDX 0x70000026
 | |
| ++#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
 | |
| ++#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
 | |
| ++#define DT_MIPS_OPTIONS	     0x70000029 /* Address of .options.  */
 | |
| ++#define DT_MIPS_INTERFACE    0x7000002a /* Address of .interface.  */
 | |
| ++#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
 | |
| ++#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
 | |
| ++#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
 | |
| ++						    function stored in GOT.  */
 | |
| ++#define DT_MIPS_PERF_SUFFIX  0x7000002e /* Default suffix of dso to be added
 | |
| ++					   by rld on dlopen() calls.  */
 | |
| ++#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
 | |
| ++#define DT_MIPS_GP_VALUE     0x70000030 /* GP value for aux GOTs.  */
 | |
| ++#define DT_MIPS_AUX_DYNAMIC  0x70000031 /* Address of aux .dynamic.  */
 | |
| ++/* The address of .got.plt in an executable using the new non-PIC ABI.  */
 | |
| ++#define DT_MIPS_PLTGOT	     0x70000032
 | |
| ++/* The base of the PLT in an executable using the new non-PIC ABI if that
 | |
| ++   PLT is writable.  For a non-writable PLT, this is omitted or has a zero
 | |
| ++   value.  */
 | |
| ++#define DT_MIPS_RWPLT        0x70000034
 | |
| ++#define DT_MIPS_NUM	     0x35
 | |
| ++
 | |
| ++/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry.  */
 | |
| ++
 | |
| ++#define RHF_NONE		   0		/* No flags */
 | |
| ++#define RHF_QUICKSTART		   (1 << 0)	/* Use quickstart */
 | |
| ++#define RHF_NOTPOT		   (1 << 1)	/* Hash size not power of 2 */
 | |
| ++#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2)	/* Ignore LD_LIBRARY_PATH */
 | |
| ++#define RHF_NO_MOVE		   (1 << 3)
 | |
| ++#define RHF_SGI_ONLY		   (1 << 4)
 | |
| ++#define RHF_GUARANTEE_INIT	   (1 << 5)
 | |
| ++#define RHF_DELTA_C_PLUS_PLUS	   (1 << 6)
 | |
| ++#define RHF_GUARANTEE_START_INIT   (1 << 7)
 | |
| ++#define RHF_PIXIE		   (1 << 8)
 | |
| ++#define RHF_DEFAULT_DELAY_LOAD	   (1 << 9)
 | |
| ++#define RHF_REQUICKSTART	   (1 << 10)
 | |
| ++#define RHF_REQUICKSTARTED	   (1 << 11)
 | |
| ++#define RHF_CORD		   (1 << 12)
 | |
| ++#define RHF_NO_UNRES_UNDEF	   (1 << 13)
 | |
| ++#define RHF_RLD_ORDER_SAFE	   (1 << 14)
 | |
| ++
 | |
| ++/* Entries found in sections of type SHT_MIPS_LIBLIST.  */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf32_Word l_name;		/* Name (string table index) */
 | |
| ++  Elf32_Word l_time_stamp;	/* Timestamp */
 | |
| ++  Elf32_Word l_checksum;	/* Checksum */
 | |
| ++  Elf32_Word l_version;		/* Interface version */
 | |
| ++  Elf32_Word l_flags;		/* Flags */
 | |
| ++} Elf32_Lib;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  Elf64_Word l_name;		/* Name (string table index) */
 | |
| ++  Elf64_Word l_time_stamp;	/* Timestamp */
 | |
| ++  Elf64_Word l_checksum;	/* Checksum */
 | |
| ++  Elf64_Word l_version;		/* Interface version */
 | |
| ++  Elf64_Word l_flags;		/* Flags */
 | |
| ++} Elf64_Lib;
 | |
| ++
 | |
| ++
 | |
| ++/* Legal values for l_flags.  */
 | |
| ++
 | |
| ++#define LL_NONE		  0
 | |
| ++#define LL_EXACT_MATCH	  (1 << 0)	/* Require exact match */
 | |
| ++#define LL_IGNORE_INT_VER (1 << 1)	/* Ignore interface version */
 | |
| ++#define LL_REQUIRE_MINOR  (1 << 2)
 | |
| ++#define LL_EXPORTS	  (1 << 3)
 | |
| ++#define LL_DELAY_LOAD	  (1 << 4)
 | |
| ++#define LL_DELTA	  (1 << 5)
 | |
| ++
 | |
| ++/* Entries found in sections of type SHT_MIPS_CONFLICT.  */
 | |
| ++
 | |
| ++typedef Elf32_Addr Elf32_Conflict;
 | |
| ++
 | |
| ++
 | |
| ++/* HPPA specific definitions.  */
 | |
| ++
 | |
| ++/* Legal values for e_flags field of Elf32_Ehdr.  */
 | |
| ++
 | |
| ++#define EF_PARISC_TRAPNIL	0x00010000 /* Trap nil pointer dereference.  */
 | |
| ++#define EF_PARISC_EXT		0x00020000 /* Program uses arch. extensions. */
 | |
| ++#define EF_PARISC_LSB		0x00040000 /* Program expects little endian. */
 | |
| ++#define EF_PARISC_WIDE		0x00080000 /* Program expects wide mode.  */
 | |
| ++#define EF_PARISC_NO_KABP	0x00100000 /* No kernel assisted branch
 | |
| ++					      prediction.  */
 | |
| ++#define EF_PARISC_LAZYSWAP	0x00400000 /* Allow lazy swapping.  */
 | |
| ++#define EF_PARISC_ARCH		0x0000ffff /* Architecture version.  */
 | |
| ++
 | |
| ++/* Defined values for `e_flags & EF_PARISC_ARCH' are:  */
 | |
| ++
 | |
| ++#define EFA_PARISC_1_0		    0x020b /* PA-RISC 1.0 big-endian.  */
 | |
| ++#define EFA_PARISC_1_1		    0x0210 /* PA-RISC 1.1 big-endian.  */
 | |
| ++#define EFA_PARISC_2_0		    0x0214 /* PA-RISC 2.0 big-endian.  */
 | |
| ++
 | |
| ++/* Additional section indeces.  */
 | |
| ++
 | |
| ++#define SHN_PARISC_ANSI_COMMON	0xff00	   /* Section for tenatively declared
 | |
| ++					      symbols in ANSI C.  */
 | |
| ++#define SHN_PARISC_HUGE_COMMON	0xff01	   /* Common blocks in huge model.  */
 | |
| ++
 | |
| ++/* Legal values for sh_type field of Elf32_Shdr.  */
 | |
| ++
 | |
| ++#define SHT_PARISC_EXT		0x70000000 /* Contains product specific ext. */
 | |
| ++#define SHT_PARISC_UNWIND	0x70000001 /* Unwind information.  */
 | |
| ++#define SHT_PARISC_DOC		0x70000002 /* Debug info for optimized code. */
 | |
| ++
 | |
| ++/* Legal values for sh_flags field of Elf32_Shdr.  */
 | |
| ++
 | |
| ++#define SHF_PARISC_SHORT	0x20000000 /* Section with short addressing. */
 | |
| ++#define SHF_PARISC_HUGE		0x40000000 /* Section far from gp.  */
 | |
| ++#define SHF_PARISC_SBP		0x80000000 /* Static branch prediction code. */
 | |
| ++
 | |
| ++/* Legal values for ST_TYPE subfield of st_info (symbol type).  */
 | |
| ++
 | |
| ++#define STT_PARISC_MILLICODE	13	/* Millicode function entry point.  */
 | |
| ++
 | |
| ++#define STT_HP_OPAQUE		(STT_LOOS + 0x1)
 | |
| ++#define STT_HP_STUB		(STT_LOOS + 0x2)
 | |
| ++
 | |
| ++/* HPPA relocs.  */
 | |
| ++
 | |
| ++#define R_PARISC_NONE		0	/* No reloc.  */
 | |
| ++#define R_PARISC_DIR32		1	/* Direct 32-bit reference.  */
 | |
| ++#define R_PARISC_DIR21L		2	/* Left 21 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR17R		3	/* Right 17 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR17F		4	/* 17 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR14R		6	/* Right 14 bits of eff. address.  */
 | |
| ++#define R_PARISC_PCREL32	9	/* 32-bit rel. address.  */
 | |
| ++#define R_PARISC_PCREL21L	10	/* Left 21 bits of rel. address.  */
 | |
| ++#define R_PARISC_PCREL17R	11	/* Right 17 bits of rel. address.  */
 | |
| ++#define R_PARISC_PCREL17F	12	/* 17 bits of rel. address.  */
 | |
| ++#define R_PARISC_PCREL14R	14	/* Right 14 bits of rel. address.  */
 | |
| ++#define R_PARISC_DPREL21L	18	/* Left 21 bits of rel. address.  */
 | |
| ++#define R_PARISC_DPREL14R	22	/* Right 14 bits of rel. address.  */
 | |
| ++#define R_PARISC_GPREL21L	26	/* GP-relative, left 21 bits.  */
 | |
| ++#define R_PARISC_GPREL14R	30	/* GP-relative, right 14 bits.  */
 | |
| ++#define R_PARISC_LTOFF21L	34	/* LT-relative, left 21 bits.  */
 | |
| ++#define R_PARISC_LTOFF14R	38	/* LT-relative, right 14 bits.  */
 | |
| ++#define R_PARISC_SECREL32	41	/* 32 bits section rel. address.  */
 | |
| ++#define R_PARISC_SEGBASE	48	/* No relocation, set segment base.  */
 | |
| ++#define R_PARISC_SEGREL32	49	/* 32 bits segment rel. address.  */
 | |
| ++#define R_PARISC_PLTOFF21L	50	/* PLT rel. address, left 21 bits.  */
 | |
| ++#define R_PARISC_PLTOFF14R	54	/* PLT rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_LTOFF_FPTR32	57	/* 32 bits LT-rel. function pointer. */
 | |
| ++#define R_PARISC_LTOFF_FPTR21L	58	/* LT-rel. fct ptr, left 21 bits. */
 | |
| ++#define R_PARISC_LTOFF_FPTR14R	62	/* LT-rel. fct ptr, right 14 bits. */
 | |
| ++#define R_PARISC_FPTR64		64	/* 64 bits function address.  */
 | |
| ++#define R_PARISC_PLABEL32	65	/* 32 bits function address.  */
 | |
| ++#define R_PARISC_PLABEL21L	66	/* Left 21 bits of fdesc address.  */
 | |
| ++#define R_PARISC_PLABEL14R	70	/* Right 14 bits of fdesc address.  */
 | |
| ++#define R_PARISC_PCREL64	72	/* 64 bits PC-rel. address.  */
 | |
| ++#define R_PARISC_PCREL22F	74	/* 22 bits PC-rel. address.  */
 | |
| ++#define R_PARISC_PCREL14WR	75	/* PC-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_PCREL14DR	76	/* PC rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_PCREL16F	77	/* 16 bits PC-rel. address.  */
 | |
| ++#define R_PARISC_PCREL16WF	78	/* 16 bits PC-rel. address.  */
 | |
| ++#define R_PARISC_PCREL16DF	79	/* 16 bits PC-rel. address.  */
 | |
| ++#define R_PARISC_DIR64		80	/* 64 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR14WR	83	/* 14 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR14DR	84	/* 14 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR16F		85	/* 16 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR16WF	86	/* 16 bits of eff. address.  */
 | |
| ++#define R_PARISC_DIR16DF	87	/* 16 bits of eff. address.  */
 | |
| ++#define R_PARISC_GPREL64	88	/* 64 bits of GP-rel. address.  */
 | |
| ++#define R_PARISC_GPREL14WR	91	/* GP-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_GPREL14DR	92	/* GP-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_GPREL16F	93	/* 16 bits GP-rel. address.  */
 | |
| ++#define R_PARISC_GPREL16WF	94	/* 16 bits GP-rel. address.  */
 | |
| ++#define R_PARISC_GPREL16DF	95	/* 16 bits GP-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF64	96	/* 64 bits LT-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF14WR	99	/* LT-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_LTOFF14DR	100	/* LT-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_LTOFF16F	101	/* 16 bits LT-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF16WF	102	/* 16 bits LT-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF16DF	103	/* 16 bits LT-rel. address.  */
 | |
| ++#define R_PARISC_SECREL64	104	/* 64 bits section rel. address.  */
 | |
| ++#define R_PARISC_SEGREL64	112	/* 64 bits segment rel. address.  */
 | |
| ++#define R_PARISC_PLTOFF14WR	115	/* PLT-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_PLTOFF14DR	116	/* PLT-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_PLTOFF16F	117	/* 16 bits LT-rel. address.  */
 | |
| ++#define R_PARISC_PLTOFF16WF	118	/* 16 bits PLT-rel. address.  */
 | |
| ++#define R_PARISC_PLTOFF16DF	119	/* 16 bits PLT-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF_FPTR64	120	/* 64 bits LT-rel. function ptr.  */
 | |
| ++#define R_PARISC_LTOFF_FPTR14WR	123	/* LT-rel. fct. ptr., right 14 bits. */
 | |
| ++#define R_PARISC_LTOFF_FPTR14DR	124	/* LT-rel. fct. ptr., right 14 bits. */
 | |
| ++#define R_PARISC_LTOFF_FPTR16F	125	/* 16 bits LT-rel. function ptr.  */
 | |
| ++#define R_PARISC_LTOFF_FPTR16WF	126	/* 16 bits LT-rel. function ptr.  */
 | |
| ++#define R_PARISC_LTOFF_FPTR16DF	127	/* 16 bits LT-rel. function ptr.  */
 | |
| ++#define R_PARISC_LORESERVE	128
 | |
| ++#define R_PARISC_COPY		128	/* Copy relocation.  */
 | |
| ++#define R_PARISC_IPLT		129	/* Dynamic reloc, imported PLT */
 | |
| ++#define R_PARISC_EPLT		130	/* Dynamic reloc, exported PLT */
 | |
| ++#define R_PARISC_TPREL32	153	/* 32 bits TP-rel. address.  */
 | |
| ++#define R_PARISC_TPREL21L	154	/* TP-rel. address, left 21 bits.  */
 | |
| ++#define R_PARISC_TPREL14R	158	/* TP-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_LTOFF_TP21L	162	/* LT-TP-rel. address, left 21 bits. */
 | |
| ++#define R_PARISC_LTOFF_TP14R	166	/* LT-TP-rel. address, right 14 bits.*/
 | |
| ++#define R_PARISC_LTOFF_TP14F	167	/* 14 bits LT-TP-rel. address.  */
 | |
| ++#define R_PARISC_TPREL64	216	/* 64 bits TP-rel. address.  */
 | |
| ++#define R_PARISC_TPREL14WR	219	/* TP-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_TPREL14DR	220	/* TP-rel. address, right 14 bits.  */
 | |
| ++#define R_PARISC_TPREL16F	221	/* 16 bits TP-rel. address.  */
 | |
| ++#define R_PARISC_TPREL16WF	222	/* 16 bits TP-rel. address.  */
 | |
| ++#define R_PARISC_TPREL16DF	223	/* 16 bits TP-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF_TP64	224	/* 64 bits LT-TP-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF_TP14WR	227	/* LT-TP-rel. address, right 14 bits.*/
 | |
| ++#define R_PARISC_LTOFF_TP14DR	228	/* LT-TP-rel. address, right 14 bits.*/
 | |
| ++#define R_PARISC_LTOFF_TP16F	229	/* 16 bits LT-TP-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF_TP16WF	230	/* 16 bits LT-TP-rel. address.  */
 | |
| ++#define R_PARISC_LTOFF_TP16DF	231	/* 16 bits LT-TP-rel. address.  */
 | |
| ++#define R_PARISC_GNU_VTENTRY	232
 | |
| ++#define R_PARISC_GNU_VTINHERIT	233
 | |
| ++#define R_PARISC_TLS_GD21L	234	/* GD 21-bit left.  */
 | |
| ++#define R_PARISC_TLS_GD14R	235	/* GD 14-bit right.  */
 | |
| ++#define R_PARISC_TLS_GDCALL	236	/* GD call to __t_g_a.  */
 | |
| ++#define R_PARISC_TLS_LDM21L	237	/* LD module 21-bit left.  */
 | |
| ++#define R_PARISC_TLS_LDM14R	238	/* LD module 14-bit right.  */
 | |
| ++#define R_PARISC_TLS_LDMCALL	239	/* LD module call to __t_g_a.  */
 | |
| ++#define R_PARISC_TLS_LDO21L	240	/* LD offset 21-bit left.  */
 | |
| ++#define R_PARISC_TLS_LDO14R	241	/* LD offset 14-bit right.  */
 | |
| ++#define R_PARISC_TLS_DTPMOD32	242	/* DTP module 32-bit.  */
 | |
| ++#define R_PARISC_TLS_DTPMOD64	243	/* DTP module 64-bit.  */
 | |
| ++#define R_PARISC_TLS_DTPOFF32	244	/* DTP offset 32-bit.  */
 | |
| ++#define R_PARISC_TLS_DTPOFF64	245	/* DTP offset 32-bit.  */
 | |
| ++#define R_PARISC_TLS_LE21L	R_PARISC_TPREL21L
 | |
| ++#define R_PARISC_TLS_LE14R	R_PARISC_TPREL14R
 | |
| ++#define R_PARISC_TLS_IE21L	R_PARISC_LTOFF_TP21L
 | |
| ++#define R_PARISC_TLS_IE14R	R_PARISC_LTOFF_TP14R
 | |
| ++#define R_PARISC_TLS_TPREL32	R_PARISC_TPREL32
 | |
| ++#define R_PARISC_TLS_TPREL64	R_PARISC_TPREL64
 | |
| ++#define R_PARISC_HIRESERVE	255
 | |
| ++
 | |
| ++/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr.  */
 | |
| ++
 | |
| ++#define PT_HP_TLS		(PT_LOOS + 0x0)
 | |
| ++#define PT_HP_CORE_NONE		(PT_LOOS + 0x1)
 | |
| ++#define PT_HP_CORE_VERSION	(PT_LOOS + 0x2)
 | |
| ++#define PT_HP_CORE_KERNEL	(PT_LOOS + 0x3)
 | |
| ++#define PT_HP_CORE_COMM		(PT_LOOS + 0x4)
 | |
| ++#define PT_HP_CORE_PROC		(PT_LOOS + 0x5)
 | |
| ++#define PT_HP_CORE_LOADABLE	(PT_LOOS + 0x6)
 | |
| ++#define PT_HP_CORE_STACK	(PT_LOOS + 0x7)
 | |
| ++#define PT_HP_CORE_SHM		(PT_LOOS + 0x8)
 | |
| ++#define PT_HP_CORE_MMF		(PT_LOOS + 0x9)
 | |
| ++#define PT_HP_PARALLEL		(PT_LOOS + 0x10)
 | |
| ++#define PT_HP_FASTBIND		(PT_LOOS + 0x11)
 | |
| ++#define PT_HP_OPT_ANNOT		(PT_LOOS + 0x12)
 | |
| ++#define PT_HP_HSL_ANNOT		(PT_LOOS + 0x13)
 | |
| ++#define PT_HP_STACK		(PT_LOOS + 0x14)
 | |
| ++
 | |
| ++#define PT_PARISC_ARCHEXT	0x70000000
 | |
| ++#define PT_PARISC_UNWIND	0x70000001
 | |
| ++
 | |
| ++/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr.  */
 | |
| ++
 | |
| ++#define PF_PARISC_SBP		0x08000000
 | |
| ++
 | |
| ++#define PF_HP_PAGE_SIZE		0x00100000
 | |
| ++#define PF_HP_FAR_SHARED	0x00200000
 | |
| ++#define PF_HP_NEAR_SHARED	0x00400000
 | |
| ++#define PF_HP_CODE		0x01000000
 | |
| ++#define PF_HP_MODIFY		0x02000000
 | |
| ++#define PF_HP_LAZYSWAP		0x04000000
 | |
| ++#define PF_HP_SBP		0x08000000
 | |
| ++
 | |
| ++
 | |
| ++/* Alpha specific definitions.  */
 | |
| ++
 | |
| ++/* Legal values for e_flags field of Elf64_Ehdr.  */
 | |
| ++
 | |
| ++#define EF_ALPHA_32BIT		1	/* All addresses must be < 2GB.  */
 | |
| ++#define EF_ALPHA_CANRELAX	2	/* Relocations for relaxing exist.  */
 | |
| ++
 | |
| ++/* Legal values for sh_type field of Elf64_Shdr.  */
 | |
| ++
 | |
| ++/* These two are primerily concerned with ECOFF debugging info.  */
 | |
| ++#define SHT_ALPHA_DEBUG		0x70000001
 | |
| ++#define SHT_ALPHA_REGINFO	0x70000002
 | |
| ++
 | |
| ++/* Legal values for sh_flags field of Elf64_Shdr.  */
 | |
| ++
 | |
| ++#define SHF_ALPHA_GPREL		0x10000000
 | |
| ++
 | |
| ++/* Legal values for st_other field of Elf64_Sym.  */
 | |
| ++#define STO_ALPHA_NOPV		0x80	/* No PV required.  */
 | |
| ++#define STO_ALPHA_STD_GPLOAD	0x88	/* PV only used for initial ldgp.  */
 | |
| ++
 | |
| ++/* Alpha relocs.  */
 | |
| ++
 | |
| ++#define R_ALPHA_NONE		0	/* No reloc */
 | |
| ++#define R_ALPHA_REFLONG		1	/* Direct 32 bit */
 | |
| ++#define R_ALPHA_REFQUAD		2	/* Direct 64 bit */
 | |
| ++#define R_ALPHA_GPREL32		3	/* GP relative 32 bit */
 | |
| ++#define R_ALPHA_LITERAL		4	/* GP relative 16 bit w/optimization */
 | |
| ++#define R_ALPHA_LITUSE		5	/* Optimization hint for LITERAL */
 | |
| ++#define R_ALPHA_GPDISP		6	/* Add displacement to GP */
 | |
| ++#define R_ALPHA_BRADDR		7	/* PC+4 relative 23 bit shifted */
 | |
| ++#define R_ALPHA_HINT		8	/* PC+4 relative 16 bit shifted */
 | |
| ++#define R_ALPHA_SREL16		9	/* PC relative 16 bit */
 | |
| ++#define R_ALPHA_SREL32		10	/* PC relative 32 bit */
 | |
| ++#define R_ALPHA_SREL64		11	/* PC relative 64 bit */
 | |
| ++#define R_ALPHA_GPRELHIGH	17	/* GP relative 32 bit, high 16 bits */
 | |
| ++#define R_ALPHA_GPRELLOW	18	/* GP relative 32 bit, low 16 bits */
 | |
| ++#define R_ALPHA_GPREL16		19	/* GP relative 16 bit */
 | |
| ++#define R_ALPHA_COPY		24	/* Copy symbol at runtime */
 | |
| ++#define R_ALPHA_GLOB_DAT	25	/* Create GOT entry */
 | |
| ++#define R_ALPHA_JMP_SLOT	26	/* Create PLT entry */
 | |
| ++#define R_ALPHA_RELATIVE	27	/* Adjust by program base */
 | |
| ++#define R_ALPHA_TLS_GD_HI	28
 | |
| ++#define R_ALPHA_TLSGD		29
 | |
| ++#define R_ALPHA_TLS_LDM		30
 | |
| ++#define R_ALPHA_DTPMOD64	31
 | |
| ++#define R_ALPHA_GOTDTPREL	32
 | |
| ++#define R_ALPHA_DTPREL64	33
 | |
| ++#define R_ALPHA_DTPRELHI	34
 | |
| ++#define R_ALPHA_DTPRELLO	35
 | |
| ++#define R_ALPHA_DTPREL16	36
 | |
| ++#define R_ALPHA_GOTTPREL	37
 | |
| ++#define R_ALPHA_TPREL64		38
 | |
| ++#define R_ALPHA_TPRELHI		39
 | |
| ++#define R_ALPHA_TPRELLO		40
 | |
| ++#define R_ALPHA_TPREL16		41
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define R_ALPHA_NUM		46
 | |
| ++
 | |
| ++/* Magic values of the LITUSE relocation addend.  */
 | |
| ++#define LITUSE_ALPHA_ADDR	0
 | |
| ++#define LITUSE_ALPHA_BASE	1
 | |
| ++#define LITUSE_ALPHA_BYTOFF	2
 | |
| ++#define LITUSE_ALPHA_JSR	3
 | |
| ++#define LITUSE_ALPHA_TLS_GD	4
 | |
| ++#define LITUSE_ALPHA_TLS_LDM	5
 | |
| ++
 | |
| ++/* Legal values for d_tag of Elf64_Dyn.  */
 | |
| ++#define DT_ALPHA_PLTRO		(DT_LOPROC + 0)
 | |
| ++#define DT_ALPHA_NUM		1
 | |
| ++
 | |
| ++/* PowerPC specific declarations */
 | |
| ++
 | |
| ++/* Values for Elf32/64_Ehdr.e_flags.  */
 | |
| ++#define EF_PPC_EMB		0x80000000	/* PowerPC embedded flag */
 | |
| ++
 | |
| ++/* Cygnus local bits below */
 | |
| ++#define EF_PPC_RELOCATABLE	0x00010000	/* PowerPC -mrelocatable flag*/
 | |
| ++#define EF_PPC_RELOCATABLE_LIB	0x00008000	/* PowerPC -mrelocatable-lib
 | |
| ++						   flag */
 | |
| ++
 | |
| ++/* PowerPC relocations defined by the ABIs */
 | |
| ++#define R_PPC_NONE		0
 | |
| ++#define R_PPC_ADDR32		1	/* 32bit absolute address */
 | |
| ++#define R_PPC_ADDR24		2	/* 26bit address, 2 bits ignored.  */
 | |
| ++#define R_PPC_ADDR16		3	/* 16bit absolute address */
 | |
| ++#define R_PPC_ADDR16_LO		4	/* lower 16bit of absolute address */
 | |
| ++#define R_PPC_ADDR16_HI		5	/* high 16bit of absolute address */
 | |
| ++#define R_PPC_ADDR16_HA		6	/* adjusted high 16bit */
 | |
| ++#define R_PPC_ADDR14		7	/* 16bit address, 2 bits ignored */
 | |
| ++#define R_PPC_ADDR14_BRTAKEN	8
 | |
| ++#define R_PPC_ADDR14_BRNTAKEN	9
 | |
| ++#define R_PPC_REL24		10	/* PC relative 26 bit */
 | |
| ++#define R_PPC_REL14		11	/* PC relative 16 bit */
 | |
| ++#define R_PPC_REL14_BRTAKEN	12
 | |
| ++#define R_PPC_REL14_BRNTAKEN	13
 | |
| ++#define R_PPC_GOT16		14
 | |
| ++#define R_PPC_GOT16_LO		15
 | |
| ++#define R_PPC_GOT16_HI		16
 | |
| ++#define R_PPC_GOT16_HA		17
 | |
| ++#define R_PPC_PLTREL24		18
 | |
| ++#define R_PPC_COPY		19
 | |
| ++#define R_PPC_GLOB_DAT		20
 | |
| ++#define R_PPC_JMP_SLOT		21
 | |
| ++#define R_PPC_RELATIVE		22
 | |
| ++#define R_PPC_LOCAL24PC		23
 | |
| ++#define R_PPC_UADDR32		24
 | |
| ++#define R_PPC_UADDR16		25
 | |
| ++#define R_PPC_REL32		26
 | |
| ++#define R_PPC_PLT32		27
 | |
| ++#define R_PPC_PLTREL32		28
 | |
| ++#define R_PPC_PLT16_LO		29
 | |
| ++#define R_PPC_PLT16_HI		30
 | |
| ++#define R_PPC_PLT16_HA		31
 | |
| ++#define R_PPC_SDAREL16		32
 | |
| ++#define R_PPC_SECTOFF		33
 | |
| ++#define R_PPC_SECTOFF_LO	34
 | |
| ++#define R_PPC_SECTOFF_HI	35
 | |
| ++#define R_PPC_SECTOFF_HA	36
 | |
| ++
 | |
| ++/* PowerPC relocations defined for the TLS access ABI.  */
 | |
| ++#define R_PPC_TLS		67 /* none	(sym+add)@tls */
 | |
| ++#define R_PPC_DTPMOD32		68 /* word32	(sym+add)@dtpmod */
 | |
| ++#define R_PPC_TPREL16		69 /* half16*	(sym+add)@tprel */
 | |
| ++#define R_PPC_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
 | |
| ++#define R_PPC_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
 | |
| ++#define R_PPC_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
 | |
| ++#define R_PPC_TPREL32		73 /* word32	(sym+add)@tprel */
 | |
| ++#define R_PPC_DTPREL16		74 /* half16*	(sym+add)@dtprel */
 | |
| ++#define R_PPC_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
 | |
| ++#define R_PPC_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
 | |
| ++#define R_PPC_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
 | |
| ++#define R_PPC_DTPREL32		78 /* word32	(sym+add)@dtprel */
 | |
| ++#define R_PPC_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
 | |
| ++#define R_PPC_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
 | |
| ++#define R_PPC_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
 | |
| ++#define R_PPC_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
 | |
| ++#define R_PPC_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
 | |
| ++#define R_PPC_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
 | |
| ++#define R_PPC_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
 | |
| ++#define R_PPC_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
 | |
| ++#define R_PPC_GOT_TPREL16	87 /* half16*	(sym+add)@got@tprel */
 | |
| ++#define R_PPC_GOT_TPREL16_LO	88 /* half16	(sym+add)@got@tprel@l */
 | |
| ++#define R_PPC_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
 | |
| ++#define R_PPC_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
 | |
| ++#define R_PPC_GOT_DTPREL16	91 /* half16*	(sym+add)@got@dtprel */
 | |
| ++#define R_PPC_GOT_DTPREL16_LO	92 /* half16*	(sym+add)@got@dtprel@l */
 | |
| ++#define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got@dtprel@h */
 | |
| ++#define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got@dtprel@ha */
 | |
| ++
 | |
| ++/* The remaining relocs are from the Embedded ELF ABI, and are not
 | |
| ++   in the SVR4 ELF ABI.  */
 | |
| ++#define R_PPC_EMB_NADDR32	101
 | |
| ++#define R_PPC_EMB_NADDR16	102
 | |
| ++#define R_PPC_EMB_NADDR16_LO	103
 | |
| ++#define R_PPC_EMB_NADDR16_HI	104
 | |
| ++#define R_PPC_EMB_NADDR16_HA	105
 | |
| ++#define R_PPC_EMB_SDAI16	106
 | |
| ++#define R_PPC_EMB_SDA2I16	107
 | |
| ++#define R_PPC_EMB_SDA2REL	108
 | |
| ++#define R_PPC_EMB_SDA21		109	/* 16 bit offset in SDA */
 | |
| ++#define R_PPC_EMB_MRKREF	110
 | |
| ++#define R_PPC_EMB_RELSEC16	111
 | |
| ++#define R_PPC_EMB_RELST_LO	112
 | |
| ++#define R_PPC_EMB_RELST_HI	113
 | |
| ++#define R_PPC_EMB_RELST_HA	114
 | |
| ++#define R_PPC_EMB_BIT_FLD	115
 | |
| ++#define R_PPC_EMB_RELSDA	116	/* 16 bit relative offset in SDA */
 | |
| ++
 | |
| ++/* Diab tool relocations.  */
 | |
| ++#define R_PPC_DIAB_SDA21_LO	180	/* like EMB_SDA21, but lower 16 bit */
 | |
| ++#define R_PPC_DIAB_SDA21_HI	181	/* like EMB_SDA21, but high 16 bit */
 | |
| ++#define R_PPC_DIAB_SDA21_HA	182	/* like EMB_SDA21, adjusted high 16 */
 | |
| ++#define R_PPC_DIAB_RELSDA_LO	183	/* like EMB_RELSDA, but lower 16 bit */
 | |
| ++#define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
 | |
| ++#define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
 | |
| ++
 | |
| ++/* GNU extension to support local ifunc.  */
 | |
| ++#define R_PPC_IRELATIVE		248
 | |
| ++
 | |
| ++/* GNU relocs used in PIC code sequences.  */
 | |
| ++#define R_PPC_REL16		249	/* half16   (sym+add-.) */
 | |
| ++#define R_PPC_REL16_LO		250	/* half16   (sym+add-.)@l */
 | |
| ++#define R_PPC_REL16_HI		251	/* half16   (sym+add-.)@h */
 | |
| ++#define R_PPC_REL16_HA		252	/* half16   (sym+add-.)@ha */
 | |
| ++
 | |
| ++/* This is a phony reloc to handle any old fashioned TOC16 references
 | |
| ++   that may still be in object files.  */
 | |
| ++#define R_PPC_TOC16		255
 | |
| ++
 | |
| ++/* PowerPC specific values for the Dyn d_tag field.  */
 | |
| ++#define DT_PPC_GOT		(DT_LOPROC + 0)
 | |
| ++#define DT_PPC_NUM		1
 | |
| ++
 | |
| ++/* PowerPC64 relocations defined by the ABIs */
 | |
| ++#define R_PPC64_NONE		R_PPC_NONE
 | |
| ++#define R_PPC64_ADDR32		R_PPC_ADDR32 /* 32bit absolute address */
 | |
| ++#define R_PPC64_ADDR24		R_PPC_ADDR24 /* 26bit address, word aligned */
 | |
| ++#define R_PPC64_ADDR16		R_PPC_ADDR16 /* 16bit absolute address */
 | |
| ++#define R_PPC64_ADDR16_LO	R_PPC_ADDR16_LO	/* lower 16bits of address */
 | |
| ++#define R_PPC64_ADDR16_HI	R_PPC_ADDR16_HI	/* high 16bits of address. */
 | |
| ++#define R_PPC64_ADDR16_HA	R_PPC_ADDR16_HA /* adjusted high 16bits.  */
 | |
| ++#define R_PPC64_ADDR14		R_PPC_ADDR14 /* 16bit address, word aligned */
 | |
| ++#define R_PPC64_ADDR14_BRTAKEN	R_PPC_ADDR14_BRTAKEN
 | |
| ++#define R_PPC64_ADDR14_BRNTAKEN	R_PPC_ADDR14_BRNTAKEN
 | |
| ++#define R_PPC64_REL24		R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
 | |
| ++#define R_PPC64_REL14		R_PPC_REL14 /* PC relative 16 bit */
 | |
| ++#define R_PPC64_REL14_BRTAKEN	R_PPC_REL14_BRTAKEN
 | |
| ++#define R_PPC64_REL14_BRNTAKEN	R_PPC_REL14_BRNTAKEN
 | |
| ++#define R_PPC64_GOT16		R_PPC_GOT16
 | |
| ++#define R_PPC64_GOT16_LO	R_PPC_GOT16_LO
 | |
| ++#define R_PPC64_GOT16_HI	R_PPC_GOT16_HI
 | |
| ++#define R_PPC64_GOT16_HA	R_PPC_GOT16_HA
 | |
| ++
 | |
| ++#define R_PPC64_COPY		R_PPC_COPY
 | |
| ++#define R_PPC64_GLOB_DAT	R_PPC_GLOB_DAT
 | |
| ++#define R_PPC64_JMP_SLOT	R_PPC_JMP_SLOT
 | |
| ++#define R_PPC64_RELATIVE	R_PPC_RELATIVE
 | |
| ++
 | |
| ++#define R_PPC64_UADDR32		R_PPC_UADDR32
 | |
| ++#define R_PPC64_UADDR16		R_PPC_UADDR16
 | |
| ++#define R_PPC64_REL32		R_PPC_REL32
 | |
| ++#define R_PPC64_PLT32		R_PPC_PLT32
 | |
| ++#define R_PPC64_PLTREL32	R_PPC_PLTREL32
 | |
| ++#define R_PPC64_PLT16_LO	R_PPC_PLT16_LO
 | |
| ++#define R_PPC64_PLT16_HI	R_PPC_PLT16_HI
 | |
| ++#define R_PPC64_PLT16_HA	R_PPC_PLT16_HA
 | |
| ++
 | |
| ++#define R_PPC64_SECTOFF		R_PPC_SECTOFF
 | |
| ++#define R_PPC64_SECTOFF_LO	R_PPC_SECTOFF_LO
 | |
| ++#define R_PPC64_SECTOFF_HI	R_PPC_SECTOFF_HI
 | |
| ++#define R_PPC64_SECTOFF_HA	R_PPC_SECTOFF_HA
 | |
| ++#define R_PPC64_ADDR30		37 /* word30 (S + A - P) >> 2 */
 | |
| ++#define R_PPC64_ADDR64		38 /* doubleword64 S + A */
 | |
| ++#define R_PPC64_ADDR16_HIGHER	39 /* half16 #higher(S + A) */
 | |
| ++#define R_PPC64_ADDR16_HIGHERA	40 /* half16 #highera(S + A) */
 | |
| ++#define R_PPC64_ADDR16_HIGHEST	41 /* half16 #highest(S + A) */
 | |
| ++#define R_PPC64_ADDR16_HIGHESTA	42 /* half16 #highesta(S + A) */
 | |
| ++#define R_PPC64_UADDR64		43 /* doubleword64 S + A */
 | |
| ++#define R_PPC64_REL64		44 /* doubleword64 S + A - P */
 | |
| ++#define R_PPC64_PLT64		45 /* doubleword64 L + A */
 | |
| ++#define R_PPC64_PLTREL64	46 /* doubleword64 L + A - P */
 | |
| ++#define R_PPC64_TOC16		47 /* half16* S + A - .TOC */
 | |
| ++#define R_PPC64_TOC16_LO	48 /* half16 #lo(S + A - .TOC.) */
 | |
| ++#define R_PPC64_TOC16_HI	49 /* half16 #hi(S + A - .TOC.) */
 | |
| ++#define R_PPC64_TOC16_HA	50 /* half16 #ha(S + A - .TOC.) */
 | |
| ++#define R_PPC64_TOC		51 /* doubleword64 .TOC */
 | |
| ++#define R_PPC64_PLTGOT16	52 /* half16* M + A */
 | |
| ++#define R_PPC64_PLTGOT16_LO	53 /* half16 #lo(M + A) */
 | |
| ++#define R_PPC64_PLTGOT16_HI	54 /* half16 #hi(M + A) */
 | |
| ++#define R_PPC64_PLTGOT16_HA	55 /* half16 #ha(M + A) */
 | |
| ++
 | |
| ++#define R_PPC64_ADDR16_DS	56 /* half16ds* (S + A) >> 2 */
 | |
| ++#define R_PPC64_ADDR16_LO_DS	57 /* half16ds  #lo(S + A) >> 2 */
 | |
| ++#define R_PPC64_GOT16_DS	58 /* half16ds* (G + A) >> 2 */
 | |
| ++#define R_PPC64_GOT16_LO_DS	59 /* half16ds  #lo(G + A) >> 2 */
 | |
| ++#define R_PPC64_PLT16_LO_DS	60 /* half16ds  #lo(L + A) >> 2 */
 | |
| ++#define R_PPC64_SECTOFF_DS	61 /* half16ds* (R + A) >> 2 */
 | |
| ++#define R_PPC64_SECTOFF_LO_DS	62 /* half16ds  #lo(R + A) >> 2 */
 | |
| ++#define R_PPC64_TOC16_DS	63 /* half16ds* (S + A - .TOC.) >> 2 */
 | |
| ++#define R_PPC64_TOC16_LO_DS	64 /* half16ds  #lo(S + A - .TOC.) >> 2 */
 | |
| ++#define R_PPC64_PLTGOT16_DS	65 /* half16ds* (M + A) >> 2 */
 | |
| ++#define R_PPC64_PLTGOT16_LO_DS	66 /* half16ds  #lo(M + A) >> 2 */
 | |
| ++
 | |
| ++/* PowerPC64 relocations defined for the TLS access ABI.  */
 | |
| ++#define R_PPC64_TLS		67 /* none	(sym+add)@tls */
 | |
| ++#define R_PPC64_DTPMOD64	68 /* doubleword64 (sym+add)@dtpmod */
 | |
| ++#define R_PPC64_TPREL16		69 /* half16*	(sym+add)@tprel */
 | |
| ++#define R_PPC64_TPREL16_LO	70 /* half16	(sym+add)@tprel@l */
 | |
| ++#define R_PPC64_TPREL16_HI	71 /* half16	(sym+add)@tprel@h */
 | |
| ++#define R_PPC64_TPREL16_HA	72 /* half16	(sym+add)@tprel@ha */
 | |
| ++#define R_PPC64_TPREL64		73 /* doubleword64 (sym+add)@tprel */
 | |
| ++#define R_PPC64_DTPREL16	74 /* half16*	(sym+add)@dtprel */
 | |
| ++#define R_PPC64_DTPREL16_LO	75 /* half16	(sym+add)@dtprel@l */
 | |
| ++#define R_PPC64_DTPREL16_HI	76 /* half16	(sym+add)@dtprel@h */
 | |
| ++#define R_PPC64_DTPREL16_HA	77 /* half16	(sym+add)@dtprel@ha */
 | |
| ++#define R_PPC64_DTPREL64	78 /* doubleword64 (sym+add)@dtprel */
 | |
| ++#define R_PPC64_GOT_TLSGD16	79 /* half16*	(sym+add)@got@tlsgd */
 | |
| ++#define R_PPC64_GOT_TLSGD16_LO	80 /* half16	(sym+add)@got@tlsgd@l */
 | |
| ++#define R_PPC64_GOT_TLSGD16_HI	81 /* half16	(sym+add)@got@tlsgd@h */
 | |
| ++#define R_PPC64_GOT_TLSGD16_HA	82 /* half16	(sym+add)@got@tlsgd@ha */
 | |
| ++#define R_PPC64_GOT_TLSLD16	83 /* half16*	(sym+add)@got@tlsld */
 | |
| ++#define R_PPC64_GOT_TLSLD16_LO	84 /* half16	(sym+add)@got@tlsld@l */
 | |
| ++#define R_PPC64_GOT_TLSLD16_HI	85 /* half16	(sym+add)@got@tlsld@h */
 | |
| ++#define R_PPC64_GOT_TLSLD16_HA	86 /* half16	(sym+add)@got@tlsld@ha */
 | |
| ++#define R_PPC64_GOT_TPREL16_DS	87 /* half16ds*	(sym+add)@got@tprel */
 | |
| ++#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
 | |
| ++#define R_PPC64_GOT_TPREL16_HI	89 /* half16	(sym+add)@got@tprel@h */
 | |
| ++#define R_PPC64_GOT_TPREL16_HA	90 /* half16	(sym+add)@got@tprel@ha */
 | |
| ++#define R_PPC64_GOT_DTPREL16_DS	91 /* half16ds*	(sym+add)@got@dtprel */
 | |
| ++#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
 | |
| ++#define R_PPC64_GOT_DTPREL16_HI	93 /* half16	(sym+add)@got@dtprel@h */
 | |
| ++#define R_PPC64_GOT_DTPREL16_HA	94 /* half16	(sym+add)@got@dtprel@ha */
 | |
| ++#define R_PPC64_TPREL16_DS	95 /* half16ds*	(sym+add)@tprel */
 | |
| ++#define R_PPC64_TPREL16_LO_DS	96 /* half16ds	(sym+add)@tprel@l */
 | |
| ++#define R_PPC64_TPREL16_HIGHER	97 /* half16	(sym+add)@tprel@higher */
 | |
| ++#define R_PPC64_TPREL16_HIGHERA	98 /* half16	(sym+add)@tprel@highera */
 | |
| ++#define R_PPC64_TPREL16_HIGHEST	99 /* half16	(sym+add)@tprel@highest */
 | |
| ++#define R_PPC64_TPREL16_HIGHESTA 100 /* half16	(sym+add)@tprel@highesta */
 | |
| ++#define R_PPC64_DTPREL16_DS	101 /* half16ds* (sym+add)@dtprel */
 | |
| ++#define R_PPC64_DTPREL16_LO_DS	102 /* half16ds	(sym+add)@dtprel@l */
 | |
| ++#define R_PPC64_DTPREL16_HIGHER	103 /* half16	(sym+add)@dtprel@higher */
 | |
| ++#define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel@highera */
 | |
| ++#define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel@highest */
 | |
| ++#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel@highesta */
 | |
| ++
 | |
| ++/* GNU extension to support local ifunc.  */
 | |
| ++#define R_PPC64_JMP_IREL	247
 | |
| ++#define R_PPC64_IRELATIVE	248
 | |
| ++#define R_PPC64_REL16		249	/* half16   (sym+add-.) */
 | |
| ++#define R_PPC64_REL16_LO	250	/* half16   (sym+add-.)@l */
 | |
| ++#define R_PPC64_REL16_HI	251	/* half16   (sym+add-.)@h */
 | |
| ++#define R_PPC64_REL16_HA	252	/* half16   (sym+add-.)@ha */
 | |
| ++
 | |
| ++/* PowerPC64 specific values for the Dyn d_tag field.  */
 | |
| ++#define DT_PPC64_GLINK  (DT_LOPROC + 0)
 | |
| ++#define DT_PPC64_OPD	(DT_LOPROC + 1)
 | |
| ++#define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
 | |
| ++#define DT_PPC64_NUM    3
 | |
| ++
 | |
| ++
 | |
| ++/* ARM specific declarations */
 | |
| ++
 | |
| ++/* Processor specific flags for the ELF header e_flags field.  */
 | |
| ++#define EF_ARM_RELEXEC		0x01
 | |
| ++#define EF_ARM_HASENTRY		0x02
 | |
| ++#define EF_ARM_INTERWORK	0x04
 | |
| ++#define EF_ARM_APCS_26		0x08
 | |
| ++#define EF_ARM_APCS_FLOAT	0x10
 | |
| ++#define EF_ARM_PIC		0x20
 | |
| ++#define EF_ARM_ALIGN8		0x40 /* 8-bit structure alignment is in use */
 | |
| ++#define EF_ARM_NEW_ABI		0x80
 | |
| ++#define EF_ARM_OLD_ABI		0x100
 | |
| ++#define EF_ARM_SOFT_FLOAT	0x200
 | |
| ++#define EF_ARM_VFP_FLOAT	0x400
 | |
| ++#define EF_ARM_MAVERICK_FLOAT	0x800
 | |
| ++
 | |
| ++
 | |
| ++/* Other constants defined in the ARM ELF spec. version B-01.  */
 | |
| ++/* NB. These conflict with values defined above.  */
 | |
| ++#define EF_ARM_SYMSARESORTED	0x04
 | |
| ++#define EF_ARM_DYNSYMSUSESEGIDX	0x08
 | |
| ++#define EF_ARM_MAPSYMSFIRST	0x10
 | |
| ++#define EF_ARM_EABIMASK		0XFF000000
 | |
| ++
 | |
| ++/* Constants defined in AAELF.  */
 | |
| ++#define EF_ARM_BE8	    0x00800000
 | |
| ++#define EF_ARM_LE8	    0x00400000
 | |
| ++
 | |
| ++#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
 | |
| ++#define EF_ARM_EABI_UNKNOWN	0x00000000
 | |
| ++#define EF_ARM_EABI_VER1	0x01000000
 | |
| ++#define EF_ARM_EABI_VER2	0x02000000
 | |
| ++#define EF_ARM_EABI_VER3	0x03000000
 | |
| ++#define EF_ARM_EABI_VER4	0x04000000
 | |
| ++#define EF_ARM_EABI_VER5	0x05000000
 | |
| ++
 | |
| ++/* Additional symbol types for Thumb.  */
 | |
| ++#define STT_ARM_TFUNC		STT_LOPROC /* A Thumb function.  */
 | |
| ++#define STT_ARM_16BIT		STT_HIPROC /* A Thumb label.  */
 | |
| ++
 | |
| ++/* ARM-specific values for sh_flags */
 | |
| ++#define SHF_ARM_ENTRYSECT	0x10000000 /* Section contains an entry point */
 | |
| ++#define SHF_ARM_COMDEF		0x80000000 /* Section may be multiply defined
 | |
| ++					      in the input to a link step.  */
 | |
| ++
 | |
| ++/* ARM-specific program header flags */
 | |
| ++#define PF_ARM_SB		0x10000000 /* Segment contains the location
 | |
| ++					      addressed by the static base. */
 | |
| ++#define PF_ARM_PI		0x20000000 /* Position-independent segment.  */
 | |
| ++#define PF_ARM_ABS		0x40000000 /* Absolute segment.  */
 | |
| ++
 | |
| ++/* Processor specific values for the Phdr p_type field.  */
 | |
| ++#define PT_ARM_EXIDX		(PT_LOPROC + 1)	/* ARM unwind segment.  */
 | |
| ++
 | |
| ++/* Processor specific values for the Shdr sh_type field.  */
 | |
| ++#define SHT_ARM_EXIDX		(SHT_LOPROC + 1) /* ARM unwind section.  */
 | |
| ++#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2) /* Preemption details.  */
 | |
| ++#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3) /* ARM attributes section.  */
 | |
| ++
 | |
| ++
 | |
| ++/* ARM relocs.  */
 | |
| ++
 | |
| ++#define R_ARM_NONE		0	/* No reloc */
 | |
| ++#define R_ARM_PC24		1	/* PC relative 26 bit branch */
 | |
| ++#define R_ARM_ABS32		2	/* Direct 32 bit  */
 | |
| ++#define R_ARM_REL32		3	/* PC relative 32 bit */
 | |
| ++#define R_ARM_PC13		4
 | |
| ++#define R_ARM_ABS16		5	/* Direct 16 bit */
 | |
| ++#define R_ARM_ABS12		6	/* Direct 12 bit */
 | |
| ++#define R_ARM_THM_ABS5		7
 | |
| ++#define R_ARM_ABS8		8	/* Direct 8 bit */
 | |
| ++#define R_ARM_SBREL32		9
 | |
| ++#define R_ARM_THM_PC22		10
 | |
| ++#define R_ARM_THM_PC8		11
 | |
| ++#define R_ARM_AMP_VCALL9	12
 | |
| ++#define R_ARM_SWI24		13	/* Obsolete static relocation.  */
 | |
| ++#define R_ARM_TLS_DESC		13      /* Dynamic relocation.  */
 | |
| ++#define R_ARM_THM_SWI8		14
 | |
| ++#define R_ARM_XPC25		15
 | |
| ++#define R_ARM_THM_XPC22		16
 | |
| ++#define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
 | |
| ++#define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
 | |
| ++#define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
 | |
| ++#define R_ARM_COPY		20	/* Copy symbol at runtime */
 | |
| ++#define R_ARM_GLOB_DAT		21	/* Create GOT entry */
 | |
| ++#define R_ARM_JUMP_SLOT		22	/* Create PLT entry */
 | |
| ++#define R_ARM_RELATIVE		23	/* Adjust by program base */
 | |
| ++#define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
 | |
| ++#define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
 | |
| ++#define R_ARM_GOT32		26	/* 32 bit GOT entry */
 | |
| ++#define R_ARM_PLT32		27	/* 32 bit PLT address */
 | |
| ++#define R_ARM_ALU_PCREL_7_0	32
 | |
| ++#define R_ARM_ALU_PCREL_15_8	33
 | |
| ++#define R_ARM_ALU_PCREL_23_15	34
 | |
| ++#define R_ARM_LDR_SBREL_11_0	35
 | |
| ++#define R_ARM_ALU_SBREL_19_12	36
 | |
| ++#define R_ARM_ALU_SBREL_27_20	37
 | |
| ++#define R_ARM_TLS_GOTDESC	90
 | |
| ++#define R_ARM_TLS_CALL		91
 | |
| ++#define R_ARM_TLS_DESCSEQ	92
 | |
| ++#define R_ARM_THM_TLS_CALL	93
 | |
| ++#define R_ARM_GNU_VTENTRY	100
 | |
| ++#define R_ARM_GNU_VTINHERIT	101
 | |
| ++#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
 | |
| ++#define R_ARM_THM_PC9		103	/* thumb conditional branch */
 | |
| ++#define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic
 | |
| ++					   thread local data */
 | |
| ++#define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic
 | |
| ++					   thread local data */
 | |
| ++#define R_ARM_TLS_LDO32		106	/* 32 bit offset relative to TLS
 | |
| ++					   block */
 | |
| ++#define R_ARM_TLS_IE32		107	/* PC-rel 32 bit for GOT entry of
 | |
| ++					   static TLS block offset */
 | |
| ++#define R_ARM_TLS_LE32		108	/* 32 bit offset relative to static
 | |
| ++					   TLS block */
 | |
| ++#define	R_ARM_THM_TLS_DESCSEQ	129
 | |
| ++#define R_ARM_IRELATIVE		160
 | |
| ++#define R_ARM_RXPC25		249
 | |
| ++#define R_ARM_RSBREL32		250
 | |
| ++#define R_ARM_THM_RPC22		251
 | |
| ++#define R_ARM_RREL32		252
 | |
| ++#define R_ARM_RABS22		253
 | |
| ++#define R_ARM_RPC24		254
 | |
| ++#define R_ARM_RBASE		255
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define R_ARM_NUM		256
 | |
| ++
 | |
| ++/* IA-64 specific declarations.  */
 | |
| ++
 | |
| ++/* Processor specific flags for the Ehdr e_flags field.  */
 | |
| ++#define EF_IA_64_MASKOS		0x0000000f	/* os-specific flags */
 | |
| ++#define EF_IA_64_ABI64		0x00000010	/* 64-bit ABI */
 | |
| ++#define EF_IA_64_ARCH		0xff000000	/* arch. version mask */
 | |
| ++
 | |
| ++/* Processor specific values for the Phdr p_type field.  */
 | |
| ++#define PT_IA_64_ARCHEXT	(PT_LOPROC + 0)	/* arch extension bits */
 | |
| ++#define PT_IA_64_UNWIND		(PT_LOPROC + 1)	/* ia64 unwind bits */
 | |
| ++#define PT_IA_64_HP_OPT_ANOT	(PT_LOOS + 0x12)
 | |
| ++#define PT_IA_64_HP_HSL_ANOT	(PT_LOOS + 0x13)
 | |
| ++#define PT_IA_64_HP_STACK	(PT_LOOS + 0x14)
 | |
| ++
 | |
| ++/* Processor specific flags for the Phdr p_flags field.  */
 | |
| ++#define PF_IA_64_NORECOV	0x80000000	/* spec insns w/o recovery */
 | |
| ++
 | |
| ++/* Processor specific values for the Shdr sh_type field.  */
 | |
| ++#define SHT_IA_64_EXT		(SHT_LOPROC + 0) /* extension bits */
 | |
| ++#define SHT_IA_64_UNWIND	(SHT_LOPROC + 1) /* unwind bits */
 | |
| ++
 | |
| ++/* Processor specific flags for the Shdr sh_flags field.  */
 | |
| ++#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
 | |
| ++#define SHF_IA_64_NORECOV	0x20000000	/* spec insns w/o recovery */
 | |
| ++
 | |
| ++/* Processor specific values for the Dyn d_tag field.  */
 | |
| ++#define DT_IA_64_PLT_RESERVE	(DT_LOPROC + 0)
 | |
| ++#define DT_IA_64_NUM		1
 | |
| ++
 | |
| ++/* IA-64 relocations.  */
 | |
| ++#define R_IA64_NONE		0x00	/* none */
 | |
| ++#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
 | |
| ++#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
 | |
| ++#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
 | |
| ++#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
 | |
| ++#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
 | |
| ++#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
 | |
| ++#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
 | |
| ++#define R_IA64_GPREL22		0x2a	/* @gprel(sym + add), add imm22 */
 | |
| ++#define R_IA64_GPREL64I		0x2b	/* @gprel(sym + add), mov imm64 */
 | |
| ++#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym + add), data4 MSB */
 | |
| ++#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym + add), data4 LSB */
 | |
| ++#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym + add), data8 MSB */
 | |
| ++#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym + add), data8 LSB */
 | |
| ++#define R_IA64_LTOFF22		0x32	/* @ltoff(sym + add), add imm22 */
 | |
| ++#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym + add), mov imm64 */
 | |
| ++#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym + add), add imm22 */
 | |
| ++#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym + add), mov imm64 */
 | |
| ++#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym + add), data8 MSB */
 | |
| ++#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym + add), data8 LSB */
 | |
| ++#define R_IA64_FPTR64I		0x43	/* @fptr(sym + add), mov imm64 */
 | |
| ++#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym + add), data4 MSB */
 | |
| ++#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym + add), data4 LSB */
 | |
| ++#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym + add), data8 MSB */
 | |
| ++#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym + add), data8 LSB */
 | |
| ++#define R_IA64_PCREL60B		0x48	/* @pcrel(sym + add), brl */
 | |
| ++#define R_IA64_PCREL21B		0x49	/* @pcrel(sym + add), ptb, call */
 | |
| ++#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym + add), chk.s */
 | |
| ++#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym + add), fchkf */
 | |
| ++#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym + add), data4 MSB */
 | |
| ++#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym + add), data4 LSB */
 | |
| ++#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym + add), data8 MSB */
 | |
| ++#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym + add), data8 LSB */
 | |
| ++#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
 | |
| ++#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
 | |
| ++#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), data4 MSB */
 | |
| ++#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), data4 LSB */
 | |
| ++#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), data8 MSB */
 | |
| ++#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), data8 LSB */
 | |
| ++#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym + add), data4 MSB */
 | |
| ++#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym + add), data4 LSB */
 | |
| ++#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym + add), data8 MSB */
 | |
| ++#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym + add), data8 LSB */
 | |
| ++#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym + add), data4 MSB */
 | |
| ++#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym + add), data4 LSB */
 | |
| ++#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym + add), data8 MSB */
 | |
| ++#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym + add), data8 LSB */
 | |
| ++#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
 | |
| ++#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
 | |
| ++#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
 | |
| ++#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
 | |
| ++#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
 | |
| ++#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
 | |
| ++#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
 | |
| ++#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
 | |
| ++#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym + add), 21bit inst */
 | |
| ++#define R_IA64_PCREL22		0x7a	/* @pcrel(sym + add), 22bit inst */
 | |
| ++#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym + add), 64bit inst */
 | |
| ++#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
 | |
| ++#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
 | |
| ++#define R_IA64_COPY		0x84	/* copy relocation */
 | |
| ++#define R_IA64_SUB		0x85	/* Addend and symbol difference */
 | |
| ++#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
 | |
| ++#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
 | |
| ++#define R_IA64_TPREL14		0x91	/* @tprel(sym + add), imm14 */
 | |
| ++#define R_IA64_TPREL22		0x92	/* @tprel(sym + add), imm22 */
 | |
| ++#define R_IA64_TPREL64I		0x93	/* @tprel(sym + add), imm64 */
 | |
| ++#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym + add), data8 MSB */
 | |
| ++#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym + add), data8 LSB */
 | |
| ++#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), imm2 */
 | |
| ++#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym + add), data8 MSB */
 | |
| ++#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym + add), data8 LSB */
 | |
| ++#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(sym + add)), imm22 */
 | |
| ++#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym + add), imm14 */
 | |
| ++#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym + add), imm22 */
 | |
| ++#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym + add), imm64 */
 | |
| ++#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym + add), data4 MSB */
 | |
| ++#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym + add), data4 LSB */
 | |
| ++#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym + add), data8 MSB */
 | |
| ++#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym + add), data8 LSB */
 | |
| ++#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
 | |
| ++
 | |
| ++/* SH specific declarations */
 | |
| ++
 | |
| ++/* Processor specific flags for the ELF header e_flags field.  */
 | |
| ++#define EF_SH_MACH_MASK		0x1f
 | |
| ++#define EF_SH_UNKNOWN		0x0
 | |
| ++#define EF_SH1			0x1
 | |
| ++#define EF_SH2			0x2
 | |
| ++#define EF_SH3			0x3
 | |
| ++#define EF_SH_DSP		0x4
 | |
| ++#define EF_SH3_DSP		0x5
 | |
| ++#define EF_SH4AL_DSP		0x6
 | |
| ++#define EF_SH3E			0x8
 | |
| ++#define EF_SH4			0x9
 | |
| ++#define EF_SH2E			0xb
 | |
| ++#define EF_SH4A			0xc
 | |
| ++#define EF_SH2A			0xd
 | |
| ++#define EF_SH4_NOFPU		0x10
 | |
| ++#define EF_SH4A_NOFPU		0x11
 | |
| ++#define EF_SH4_NOMMU_NOFPU	0x12
 | |
| ++#define EF_SH2A_NOFPU		0x13
 | |
| ++#define EF_SH3_NOMMU		0x14
 | |
| ++#define EF_SH2A_SH4_NOFPU	0x15
 | |
| ++#define EF_SH2A_SH3_NOFPU	0x16
 | |
| ++#define EF_SH2A_SH4		0x17
 | |
| ++#define EF_SH2A_SH3E		0x18
 | |
| ++
 | |
| ++/* SH relocs.  */
 | |
| ++#define	R_SH_NONE		0
 | |
| ++#define	R_SH_DIR32		1
 | |
| ++#define	R_SH_REL32		2
 | |
| ++#define	R_SH_DIR8WPN		3
 | |
| ++#define	R_SH_IND12W		4
 | |
| ++#define	R_SH_DIR8WPL		5
 | |
| ++#define	R_SH_DIR8WPZ		6
 | |
| ++#define	R_SH_DIR8BP		7
 | |
| ++#define	R_SH_DIR8W		8
 | |
| ++#define	R_SH_DIR8L		9
 | |
| ++#define	R_SH_SWITCH16		25
 | |
| ++#define	R_SH_SWITCH32		26
 | |
| ++#define	R_SH_USES		27
 | |
| ++#define	R_SH_COUNT		28
 | |
| ++#define	R_SH_ALIGN		29
 | |
| ++#define	R_SH_CODE		30
 | |
| ++#define	R_SH_DATA		31
 | |
| ++#define	R_SH_LABEL		32
 | |
| ++#define	R_SH_SWITCH8		33
 | |
| ++#define	R_SH_GNU_VTINHERIT	34
 | |
| ++#define	R_SH_GNU_VTENTRY	35
 | |
| ++#define	R_SH_TLS_GD_32		144
 | |
| ++#define	R_SH_TLS_LD_32		145
 | |
| ++#define	R_SH_TLS_LDO_32		146
 | |
| ++#define	R_SH_TLS_IE_32		147
 | |
| ++#define	R_SH_TLS_LE_32		148
 | |
| ++#define	R_SH_TLS_DTPMOD32	149
 | |
| ++#define	R_SH_TLS_DTPOFF32	150
 | |
| ++#define	R_SH_TLS_TPOFF32	151
 | |
| ++#define	R_SH_GOT32		160
 | |
| ++#define	R_SH_PLT32		161
 | |
| ++#define	R_SH_COPY		162
 | |
| ++#define	R_SH_GLOB_DAT		163
 | |
| ++#define	R_SH_JMP_SLOT		164
 | |
| ++#define	R_SH_RELATIVE		165
 | |
| ++#define	R_SH_GOTOFF		166
 | |
| ++#define	R_SH_GOTPC		167
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define	R_SH_NUM		256
 | |
| ++
 | |
| ++/* S/390 specific definitions.  */
 | |
| ++
 | |
| ++/* Valid values for the e_flags field.  */
 | |
| ++
 | |
| ++#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
 | |
| ++
 | |
| ++/* Additional s390 relocs */
 | |
| ++
 | |
| ++#define R_390_NONE		0	/* No reloc.  */
 | |
| ++#define R_390_8			1	/* Direct 8 bit.  */
 | |
| ++#define R_390_12		2	/* Direct 12 bit.  */
 | |
| ++#define R_390_16		3	/* Direct 16 bit.  */
 | |
| ++#define R_390_32		4	/* Direct 32 bit.  */
 | |
| ++#define R_390_PC32		5	/* PC relative 32 bit.	*/
 | |
| ++#define R_390_GOT12		6	/* 12 bit GOT offset.  */
 | |
| ++#define R_390_GOT32		7	/* 32 bit GOT offset.  */
 | |
| ++#define R_390_PLT32		8	/* 32 bit PC relative PLT address.  */
 | |
| ++#define R_390_COPY		9	/* Copy symbol at runtime.  */
 | |
| ++#define R_390_GLOB_DAT		10	/* Create GOT entry.  */
 | |
| ++#define R_390_JMP_SLOT		11	/* Create PLT entry.  */
 | |
| ++#define R_390_RELATIVE		12	/* Adjust by program base.  */
 | |
| ++#define R_390_GOTOFF32		13	/* 32 bit offset to GOT.	 */
 | |
| ++#define R_390_GOTPC		14	/* 32 bit PC relative offset to GOT.  */
 | |
| ++#define R_390_GOT16		15	/* 16 bit GOT offset.  */
 | |
| ++#define R_390_PC16		16	/* PC relative 16 bit.	*/
 | |
| ++#define R_390_PC16DBL		17	/* PC relative 16 bit shifted by 1.  */
 | |
| ++#define R_390_PLT16DBL		18	/* 16 bit PC rel. PLT shifted by 1.  */
 | |
| ++#define R_390_PC32DBL		19	/* PC relative 32 bit shifted by 1.  */
 | |
| ++#define R_390_PLT32DBL		20	/* 32 bit PC rel. PLT shifted by 1.  */
 | |
| ++#define R_390_GOTPCDBL		21	/* 32 bit PC rel. GOT shifted by 1.  */
 | |
| ++#define R_390_64		22	/* Direct 64 bit.  */
 | |
| ++#define R_390_PC64		23	/* PC relative 64 bit.	*/
 | |
| ++#define R_390_GOT64		24	/* 64 bit GOT offset.  */
 | |
| ++#define R_390_PLT64		25	/* 64 bit PC relative PLT address.  */
 | |
| ++#define R_390_GOTENT		26	/* 32 bit PC rel. to GOT entry >> 1. */
 | |
| ++#define R_390_GOTOFF16		27	/* 16 bit offset to GOT. */
 | |
| ++#define R_390_GOTOFF64		28	/* 64 bit offset to GOT. */
 | |
| ++#define R_390_GOTPLT12		29	/* 12 bit offset to jump slot.	*/
 | |
| ++#define R_390_GOTPLT16		30	/* 16 bit offset to jump slot.	*/
 | |
| ++#define R_390_GOTPLT32		31	/* 32 bit offset to jump slot.	*/
 | |
| ++#define R_390_GOTPLT64		32	/* 64 bit offset to jump slot.	*/
 | |
| ++#define R_390_GOTPLTENT		33	/* 32 bit rel. offset to jump slot.  */
 | |
| ++#define R_390_PLTOFF16		34	/* 16 bit offset from GOT to PLT. */
 | |
| ++#define R_390_PLTOFF32		35	/* 32 bit offset from GOT to PLT. */
 | |
| ++#define R_390_PLTOFF64		36	/* 16 bit offset from GOT to PLT. */
 | |
| ++#define R_390_TLS_LOAD		37	/* Tag for load insn in TLS code.  */
 | |
| ++#define R_390_TLS_GDCALL	38	/* Tag for function call in general
 | |
| ++					   dynamic TLS code. */
 | |
| ++#define R_390_TLS_LDCALL	39	/* Tag for function call in local
 | |
| ++					   dynamic TLS code. */
 | |
| ++#define R_390_TLS_GD32		40	/* Direct 32 bit for general dynamic
 | |
| ++					   thread local data.  */
 | |
| ++#define R_390_TLS_GD64		41	/* Direct 64 bit for general dynamic
 | |
| ++					  thread local data.  */
 | |
| ++#define R_390_TLS_GOTIE12	42	/* 12 bit GOT offset for static TLS
 | |
| ++					   block offset.  */
 | |
| ++#define R_390_TLS_GOTIE32	43	/* 32 bit GOT offset for static TLS
 | |
| ++					   block offset.  */
 | |
| ++#define R_390_TLS_GOTIE64	44	/* 64 bit GOT offset for static TLS
 | |
| ++					   block offset. */
 | |
| ++#define R_390_TLS_LDM32		45	/* Direct 32 bit for local dynamic
 | |
| ++					   thread local data in LE code.  */
 | |
| ++#define R_390_TLS_LDM64		46	/* Direct 64 bit for local dynamic
 | |
| ++					   thread local data in LE code.  */
 | |
| ++#define R_390_TLS_IE32		47	/* 32 bit address of GOT entry for
 | |
| ++					   negated static TLS block offset.  */
 | |
| ++#define R_390_TLS_IE64		48	/* 64 bit address of GOT entry for
 | |
| ++					   negated static TLS block offset.  */
 | |
| ++#define R_390_TLS_IEENT		49	/* 32 bit rel. offset to GOT entry for
 | |
| ++					   negated static TLS block offset.  */
 | |
| ++#define R_390_TLS_LE32		50	/* 32 bit negated offset relative to
 | |
| ++					   static TLS block.  */
 | |
| ++#define R_390_TLS_LE64		51	/* 64 bit negated offset relative to
 | |
| ++					   static TLS block.  */
 | |
| ++#define R_390_TLS_LDO32		52	/* 32 bit offset relative to TLS
 | |
| ++					   block.  */
 | |
| ++#define R_390_TLS_LDO64		53	/* 64 bit offset relative to TLS
 | |
| ++					   block.  */
 | |
| ++#define R_390_TLS_DTPMOD	54	/* ID of module containing symbol.  */
 | |
| ++#define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
 | |
| ++#define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
 | |
| ++					   block.  */
 | |
| ++#define R_390_20		57	/* Direct 20 bit.  */
 | |
| ++#define R_390_GOT20		58	/* 20 bit GOT offset.  */
 | |
| ++#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
 | |
| ++#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
 | |
| ++					   block offset.  */
 | |
| ++#define R_390_IRELATIVE         61      /* STT_GNU_IFUNC relocation.  */
 | |
| ++/* Keep this the last entry.  */
 | |
| ++#define R_390_NUM		62
 | |
| ++
 | |
| ++
 | |
| ++/* CRIS relocations.  */
 | |
| ++#define R_CRIS_NONE		0
 | |
| ++#define R_CRIS_8		1
 | |
| ++#define R_CRIS_16		2
 | |
| ++#define R_CRIS_32		3
 | |
| ++#define R_CRIS_8_PCREL		4
 | |
| ++#define R_CRIS_16_PCREL		5
 | |
| ++#define R_CRIS_32_PCREL		6
 | |
| ++#define R_CRIS_GNU_VTINHERIT	7
 | |
| ++#define R_CRIS_GNU_VTENTRY	8
 | |
| ++#define R_CRIS_COPY		9
 | |
| ++#define R_CRIS_GLOB_DAT		10
 | |
| ++#define R_CRIS_JUMP_SLOT	11
 | |
| ++#define R_CRIS_RELATIVE		12
 | |
| ++#define R_CRIS_16_GOT		13
 | |
| ++#define R_CRIS_32_GOT		14
 | |
| ++#define R_CRIS_16_GOTPLT	15
 | |
| ++#define R_CRIS_32_GOTPLT	16
 | |
| ++#define R_CRIS_32_GOTREL	17
 | |
| ++#define R_CRIS_32_PLT_GOTREL	18
 | |
| ++#define R_CRIS_32_PLT_PCREL	19
 | |
| ++
 | |
| ++#define R_CRIS_NUM		20
 | |
| ++
 | |
| ++
 | |
| ++/* AMD x86-64 relocations.  */
 | |
| ++#define R_X86_64_NONE		0	/* No reloc */
 | |
| ++#define R_X86_64_64		1	/* Direct 64 bit  */
 | |
| ++#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
 | |
| ++#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
 | |
| ++#define R_X86_64_PLT32		4	/* 32 bit PLT address */
 | |
| ++#define R_X86_64_COPY		5	/* Copy symbol at runtime */
 | |
| ++#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
 | |
| ++#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
 | |
| ++#define R_X86_64_RELATIVE	8	/* Adjust by program base */
 | |
| ++#define R_X86_64_GOTPCREL	9	/* 32 bit signed PC relative
 | |
| ++					   offset to GOT */
 | |
| ++#define R_X86_64_32		10	/* Direct 32 bit zero extended */
 | |
| ++#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
 | |
| ++#define R_X86_64_16		12	/* Direct 16 bit zero extended */
 | |
| ++#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
 | |
| ++#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
 | |
| ++#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
 | |
| ++#define R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
 | |
| ++#define R_X86_64_DTPOFF64	17	/* Offset in module's TLS block */
 | |
| ++#define R_X86_64_TPOFF64	18	/* Offset in initial TLS block */
 | |
| ++#define R_X86_64_TLSGD		19	/* 32 bit signed PC relative offset
 | |
| ++					   to two GOT entries for GD symbol */
 | |
| ++#define R_X86_64_TLSLD		20	/* 32 bit signed PC relative offset
 | |
| ++					   to two GOT entries for LD symbol */
 | |
| ++#define R_X86_64_DTPOFF32	21	/* Offset in TLS block */
 | |
| ++#define R_X86_64_GOTTPOFF	22	/* 32 bit signed PC relative offset
 | |
| ++					   to GOT entry for IE symbol */
 | |
| ++#define R_X86_64_TPOFF32	23	/* Offset in initial TLS block */
 | |
| ++#define R_X86_64_PC64		24	/* PC relative 64 bit */
 | |
| ++#define R_X86_64_GOTOFF64	25	/* 64 bit offset to GOT */
 | |
| ++#define R_X86_64_GOTPC32	26	/* 32 bit signed pc relative
 | |
| ++					   offset to GOT */
 | |
| ++#define R_X86_64_GOT64		27	/* 64-bit GOT entry offset */
 | |
| ++#define R_X86_64_GOTPCREL64	28	/* 64-bit PC relative offset
 | |
| ++					   to GOT entry */
 | |
| ++#define R_X86_64_GOTPC64	29	/* 64-bit PC relative offset to GOT */
 | |
| ++#define R_X86_64_GOTPLT64	30 	/* like GOT64, says PLT entry needed */
 | |
| ++#define R_X86_64_PLTOFF64	31	/* 64-bit GOT relative offset
 | |
| ++					   to PLT entry */
 | |
| ++#define R_X86_64_SIZE32		32	/* Size of symbol plus 32-bit addend */
 | |
| ++#define R_X86_64_SIZE64		33	/* Size of symbol plus 64-bit addend */
 | |
| ++#define R_X86_64_GOTPC32_TLSDESC 34	/* GOT offset for TLS descriptor.  */
 | |
| ++#define R_X86_64_TLSDESC_CALL   35	/* Marker for call through TLS
 | |
| ++					   descriptor.  */
 | |
| ++#define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
 | |
| ++#define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
 | |
| ++#define R_X86_64_RELATIVE64	38	/* 64-bit adjust by program base */
 | |
| ++
 | |
| ++#define R_X86_64_NUM		39
 | |
| ++
 | |
| ++
 | |
| ++/* AM33 relocations.  */
 | |
| ++#define R_MN10300_NONE		0	/* No reloc.  */
 | |
| ++#define R_MN10300_32		1	/* Direct 32 bit.  */
 | |
| ++#define R_MN10300_16		2	/* Direct 16 bit.  */
 | |
| ++#define R_MN10300_8		3	/* Direct 8 bit.  */
 | |
| ++#define R_MN10300_PCREL32	4	/* PC-relative 32-bit.  */
 | |
| ++#define R_MN10300_PCREL16	5	/* PC-relative 16-bit signed.  */
 | |
| ++#define R_MN10300_PCREL8	6	/* PC-relative 8-bit signed.  */
 | |
| ++#define R_MN10300_GNU_VTINHERIT	7	/* Ancient C++ vtable garbage... */
 | |
| ++#define R_MN10300_GNU_VTENTRY	8	/* ... collection annotation.  */
 | |
| ++#define R_MN10300_24		9	/* Direct 24 bit.  */
 | |
| ++#define R_MN10300_GOTPC32	10	/* 32-bit PCrel offset to GOT.  */
 | |
| ++#define R_MN10300_GOTPC16	11	/* 16-bit PCrel offset to GOT.  */
 | |
| ++#define R_MN10300_GOTOFF32	12	/* 32-bit offset from GOT.  */
 | |
| ++#define R_MN10300_GOTOFF24	13	/* 24-bit offset from GOT.  */
 | |
| ++#define R_MN10300_GOTOFF16	14	/* 16-bit offset from GOT.  */
 | |
| ++#define R_MN10300_PLT32		15	/* 32-bit PCrel to PLT entry.  */
 | |
| ++#define R_MN10300_PLT16		16	/* 16-bit PCrel to PLT entry.  */
 | |
| ++#define R_MN10300_GOT32		17	/* 32-bit offset to GOT entry.  */
 | |
| ++#define R_MN10300_GOT24		18	/* 24-bit offset to GOT entry.  */
 | |
| ++#define R_MN10300_GOT16		19	/* 16-bit offset to GOT entry.  */
 | |
| ++#define R_MN10300_COPY		20	/* Copy symbol at runtime.  */
 | |
| ++#define R_MN10300_GLOB_DAT	21	/* Create GOT entry.  */
 | |
| ++#define R_MN10300_JMP_SLOT	22	/* Create PLT entry.  */
 | |
| ++#define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
 | |
| ++
 | |
| ++#define R_MN10300_NUM		24
 | |
| ++
 | |
| ++
 | |
| ++/* M32R relocs.  */
 | |
| ++#define R_M32R_NONE		0	/* No reloc. */
 | |
| ++#define R_M32R_16		1	/* Direct 16 bit. */
 | |
| ++#define R_M32R_32		2	/* Direct 32 bit. */
 | |
| ++#define R_M32R_24		3	/* Direct 24 bit. */
 | |
| ++#define R_M32R_10_PCREL		4	/* PC relative 10 bit shifted. */
 | |
| ++#define R_M32R_18_PCREL		5	/* PC relative 18 bit shifted. */
 | |
| ++#define R_M32R_26_PCREL		6	/* PC relative 26 bit shifted. */
 | |
| ++#define R_M32R_HI16_ULO		7	/* High 16 bit with unsigned low. */
 | |
| ++#define R_M32R_HI16_SLO		8	/* High 16 bit with signed low. */
 | |
| ++#define R_M32R_LO16		9	/* Low 16 bit. */
 | |
| ++#define R_M32R_SDA16		10	/* 16 bit offset in SDA. */
 | |
| ++#define R_M32R_GNU_VTINHERIT	11
 | |
| ++#define R_M32R_GNU_VTENTRY	12
 | |
| ++/* M32R relocs use SHT_RELA.  */
 | |
| ++#define R_M32R_16_RELA		33	/* Direct 16 bit. */
 | |
| ++#define R_M32R_32_RELA		34	/* Direct 32 bit. */
 | |
| ++#define R_M32R_24_RELA		35	/* Direct 24 bit. */
 | |
| ++#define R_M32R_10_PCREL_RELA	36	/* PC relative 10 bit shifted. */
 | |
| ++#define R_M32R_18_PCREL_RELA	37	/* PC relative 18 bit shifted. */
 | |
| ++#define R_M32R_26_PCREL_RELA	38	/* PC relative 26 bit shifted. */
 | |
| ++#define R_M32R_HI16_ULO_RELA	39	/* High 16 bit with unsigned low */
 | |
| ++#define R_M32R_HI16_SLO_RELA	40	/* High 16 bit with signed low */
 | |
| ++#define R_M32R_LO16_RELA	41	/* Low 16 bit */
 | |
| ++#define R_M32R_SDA16_RELA	42	/* 16 bit offset in SDA */
 | |
| ++#define R_M32R_RELA_GNU_VTINHERIT	43
 | |
| ++#define R_M32R_RELA_GNU_VTENTRY	44
 | |
| ++#define R_M32R_REL32		45	/* PC relative 32 bit.  */
 | |
| ++
 | |
| ++#define R_M32R_GOT24		48	/* 24 bit GOT entry */
 | |
| ++#define R_M32R_26_PLTREL	49	/* 26 bit PC relative to PLT shifted */
 | |
| ++#define R_M32R_COPY		50	/* Copy symbol at runtime */
 | |
| ++#define R_M32R_GLOB_DAT		51	/* Create GOT entry */
 | |
| ++#define R_M32R_JMP_SLOT		52	/* Create PLT entry */
 | |
| ++#define R_M32R_RELATIVE		53	/* Adjust by program base */
 | |
| ++#define R_M32R_GOTOFF		54	/* 24 bit offset to GOT */
 | |
| ++#define R_M32R_GOTPC24		55	/* 24 bit PC relative offset to GOT */
 | |
| ++#define R_M32R_GOT16_HI_ULO	56	/* High 16 bit GOT entry with unsigned
 | |
| ++					   low */
 | |
| ++#define R_M32R_GOT16_HI_SLO	57	/* High 16 bit GOT entry with signed
 | |
| ++					   low */
 | |
| ++#define R_M32R_GOT16_LO		58	/* Low 16 bit GOT entry */
 | |
| ++#define R_M32R_GOTPC_HI_ULO	59	/* High 16 bit PC relative offset to
 | |
| ++					   GOT with unsigned low */
 | |
| ++#define R_M32R_GOTPC_HI_SLO	60	/* High 16 bit PC relative offset to
 | |
| ++					   GOT with signed low */
 | |
| ++#define R_M32R_GOTPC_LO		61	/* Low 16 bit PC relative offset to
 | |
| ++					   GOT */
 | |
| ++#define R_M32R_GOTOFF_HI_ULO	62	/* High 16 bit offset to GOT
 | |
| ++					   with unsigned low */
 | |
| ++#define R_M32R_GOTOFF_HI_SLO	63	/* High 16 bit offset to GOT
 | |
| ++					   with signed low */
 | |
| ++#define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
 | |
| ++#define R_M32R_NUM		256	/* Keep this the last entry. */
 | |
| ++
 | |
| ++
 | |
| ++/* TILEPro relocations.  */
 | |
| ++#define R_TILEPRO_NONE		0	/* No reloc */
 | |
| ++#define R_TILEPRO_32		1	/* Direct 32 bit */
 | |
| ++#define R_TILEPRO_16		2	/* Direct 16 bit */
 | |
| ++#define R_TILEPRO_8		3	/* Direct 8 bit */
 | |
| ++#define R_TILEPRO_32_PCREL	4	/* PC relative 32 bit */
 | |
| ++#define R_TILEPRO_16_PCREL	5	/* PC relative 16 bit */
 | |
| ++#define R_TILEPRO_8_PCREL	6	/* PC relative 8 bit */
 | |
| ++#define R_TILEPRO_LO16		7	/* Low 16 bit */
 | |
| ++#define R_TILEPRO_HI16		8	/* High 16 bit */
 | |
| ++#define R_TILEPRO_HA16		9	/* High 16 bit, adjusted */
 | |
| ++#define R_TILEPRO_COPY		10	/* Copy relocation */
 | |
| ++#define R_TILEPRO_GLOB_DAT	11	/* Create GOT entry */
 | |
| ++#define R_TILEPRO_JMP_SLOT	12	/* Create PLT entry */
 | |
| ++#define R_TILEPRO_RELATIVE	13	/* Adjust by program base */
 | |
| ++#define R_TILEPRO_BROFF_X1	14	/* X1 pipe branch offset */
 | |
| ++#define R_TILEPRO_JOFFLONG_X1	15	/* X1 pipe jump offset */
 | |
| ++#define R_TILEPRO_JOFFLONG_X1_PLT 16	/* X1 pipe jump offset to PLT */
 | |
| ++#define R_TILEPRO_IMM8_X0	17	/* X0 pipe 8-bit */
 | |
| ++#define R_TILEPRO_IMM8_Y0	18	/* Y0 pipe 8-bit */
 | |
| ++#define R_TILEPRO_IMM8_X1	19	/* X1 pipe 8-bit */
 | |
| ++#define R_TILEPRO_IMM8_Y1	20	/* Y1 pipe 8-bit */
 | |
| ++#define R_TILEPRO_MT_IMM15_X1	21	/* X1 pipe mtspr */
 | |
| ++#define R_TILEPRO_MF_IMM15_X1	22	/* X1 pipe mfspr */
 | |
| ++#define R_TILEPRO_IMM16_X0	23	/* X0 pipe 16-bit */
 | |
| ++#define R_TILEPRO_IMM16_X1	24	/* X1 pipe 16-bit */
 | |
| ++#define R_TILEPRO_IMM16_X0_LO	25	/* X0 pipe low 16-bit */
 | |
| ++#define R_TILEPRO_IMM16_X1_LO	26	/* X1 pipe low 16-bit */
 | |
| ++#define R_TILEPRO_IMM16_X0_HI	27	/* X0 pipe high 16-bit */
 | |
| ++#define R_TILEPRO_IMM16_X1_HI	28	/* X1 pipe high 16-bit */
 | |
| ++#define R_TILEPRO_IMM16_X0_HA	29	/* X0 pipe high 16-bit, adjusted */
 | |
| ++#define R_TILEPRO_IMM16_X1_HA	30	/* X1 pipe high 16-bit, adjusted */
 | |
| ++#define R_TILEPRO_IMM16_X0_PCREL 31	/* X0 pipe PC relative 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X1_PCREL 32	/* X1 pipe PC relative 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X0_LO_PCREL 33	/* X0 pipe PC relative low 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X1_LO_PCREL 34	/* X1 pipe PC relative low 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X0_HI_PCREL 35	/* X0 pipe PC relative high 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X1_HI_PCREL 36	/* X1 pipe PC relative high 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X0_HA_PCREL 37	/* X0 pipe PC relative ha() 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X1_HA_PCREL 38	/* X1 pipe PC relative ha() 16 bit */
 | |
| ++#define R_TILEPRO_IMM16_X0_GOT	39	/* X0 pipe 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_GOT	40	/* X1 pipe 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_GOT_LO 41	/* X0 pipe low 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_GOT_LO 42	/* X1 pipe low 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_GOT_HI 43	/* X0 pipe high 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_GOT_HI 44	/* X1 pipe high 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_GOT_HA 45	/* X0 pipe ha() 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_GOT_HA 46	/* X1 pipe ha() 16-bit GOT offset */
 | |
| ++#define R_TILEPRO_MMSTART_X0	47	/* X0 pipe mm "start" */
 | |
| ++#define R_TILEPRO_MMEND_X0	48	/* X0 pipe mm "end" */
 | |
| ++#define R_TILEPRO_MMSTART_X1	49	/* X1 pipe mm "start" */
 | |
| ++#define R_TILEPRO_MMEND_X1	50	/* X1 pipe mm "end" */
 | |
| ++#define R_TILEPRO_SHAMT_X0	51	/* X0 pipe shift amount */
 | |
| ++#define R_TILEPRO_SHAMT_X1	52	/* X1 pipe shift amount */
 | |
| ++#define R_TILEPRO_SHAMT_Y0	53	/* Y0 pipe shift amount */
 | |
| ++#define R_TILEPRO_SHAMT_Y1	54	/* Y1 pipe shift amount */
 | |
| ++#define R_TILEPRO_DEST_IMM8_X1	55	/* X1 pipe destination 8-bit */
 | |
| ++/* Relocs 56-59 are currently not defined.  */
 | |
| ++#define R_TILEPRO_TLS_GD_CALL	60	/* "jal" for TLS GD */
 | |
| ++#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61	/* X0 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62	/* X1 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63	/* Y0 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64	/* Y1 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEPRO_TLS_IE_LOAD	65	/* "lw_tls" for TLS IE */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_GD 66	/* X0 pipe 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_GD 67	/* X1 pipe 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68	/* X0 pipe low 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69	/* X1 pipe low 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70	/* X0 pipe high 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71	/* X1 pipe high 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72	/* X0 pipe ha() 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73	/* X1 pipe ha() 16-bit TLS GD offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_IE 74	/* X0 pipe 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_IE 75	/* X1 pipe 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76	/* X0 pipe low 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77	/* X1 pipe low 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78	/* X0 pipe high 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79	/* X1 pipe high 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80	/* X0 pipe ha() 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81	/* X1 pipe ha() 16-bit TLS IE offset */
 | |
| ++#define R_TILEPRO_TLS_DTPMOD32	82	/* ID of module containing symbol */
 | |
| ++#define R_TILEPRO_TLS_DTPOFF32	83	/* Offset in TLS block */
 | |
| ++#define R_TILEPRO_TLS_TPOFF32	84	/* Offset in static TLS block */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_LE 85	/* X0 pipe 16-bit TLS LE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_LE 86	/* X1 pipe 16-bit TLS LE offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87	/* X0 pipe low 16-bit TLS LE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88	/* X1 pipe low 16-bit TLS LE offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89	/* X0 pipe high 16-bit TLS LE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90	/* X1 pipe high 16-bit TLS LE offset */
 | |
| ++#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91	/* X0 pipe ha() 16-bit TLS LE offset */
 | |
| ++#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92	/* X1 pipe ha() 16-bit TLS LE offset */
 | |
| ++
 | |
| ++#define R_TILEPRO_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
 | |
| ++#define R_TILEPRO_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
 | |
| ++
 | |
| ++#define R_TILEPRO_NUM		130
 | |
| ++
 | |
| ++
 | |
| ++/* TILE-Gx relocations.  */
 | |
| ++#define R_TILEGX_NONE		0	/* No reloc */
 | |
| ++#define R_TILEGX_64		1	/* Direct 64 bit */
 | |
| ++#define R_TILEGX_32		2	/* Direct 32 bit */
 | |
| ++#define R_TILEGX_16		3	/* Direct 16 bit */
 | |
| ++#define R_TILEGX_8		4	/* Direct 8 bit */
 | |
| ++#define R_TILEGX_64_PCREL	5	/* PC relative 64 bit */
 | |
| ++#define R_TILEGX_32_PCREL	6	/* PC relative 32 bit */
 | |
| ++#define R_TILEGX_16_PCREL	7	/* PC relative 16 bit */
 | |
| ++#define R_TILEGX_8_PCREL	8	/* PC relative 8 bit */
 | |
| ++#define R_TILEGX_HW0		9	/* hword 0 16-bit */
 | |
| ++#define R_TILEGX_HW1		10	/* hword 1 16-bit */
 | |
| ++#define R_TILEGX_HW2		11	/* hword 2 16-bit */
 | |
| ++#define R_TILEGX_HW3		12	/* hword 3 16-bit */
 | |
| ++#define R_TILEGX_HW0_LAST	13	/* last hword 0 16-bit */
 | |
| ++#define R_TILEGX_HW1_LAST	14	/* last hword 1 16-bit */
 | |
| ++#define R_TILEGX_HW2_LAST	15	/* last hword 2 16-bit */
 | |
| ++#define R_TILEGX_COPY		16	/* Copy relocation */
 | |
| ++#define R_TILEGX_GLOB_DAT	17	/* Create GOT entry */
 | |
| ++#define R_TILEGX_JMP_SLOT	18	/* Create PLT entry */
 | |
| ++#define R_TILEGX_RELATIVE	19	/* Adjust by program base */
 | |
| ++#define R_TILEGX_BROFF_X1	20	/* X1 pipe branch offset */
 | |
| ++#define R_TILEGX_JUMPOFF_X1	21	/* X1 pipe jump offset */
 | |
| ++#define R_TILEGX_JUMPOFF_X1_PLT	22	/* X1 pipe jump offset to PLT */
 | |
| ++#define R_TILEGX_IMM8_X0	23	/* X0 pipe 8-bit */
 | |
| ++#define R_TILEGX_IMM8_Y0	24	/* Y0 pipe 8-bit */
 | |
| ++#define R_TILEGX_IMM8_X1	25	/* X1 pipe 8-bit */
 | |
| ++#define R_TILEGX_IMM8_Y1	26	/* Y1 pipe 8-bit */
 | |
| ++#define R_TILEGX_DEST_IMM8_X1	27	/* X1 pipe destination 8-bit */
 | |
| ++#define R_TILEGX_MT_IMM14_X1	28	/* X1 pipe mtspr */
 | |
| ++#define R_TILEGX_MF_IMM14_X1	29	/* X1 pipe mfspr */
 | |
| ++#define R_TILEGX_MMSTART_X0	30	/* X0 pipe mm "start" */
 | |
| ++#define R_TILEGX_MMEND_X0	31	/* X0 pipe mm "end" */
 | |
| ++#define R_TILEGX_SHAMT_X0	32	/* X0 pipe shift amount */
 | |
| ++#define R_TILEGX_SHAMT_X1	33	/* X1 pipe shift amount */
 | |
| ++#define R_TILEGX_SHAMT_Y0	34	/* Y0 pipe shift amount */
 | |
| ++#define R_TILEGX_SHAMT_Y1	35	/* Y1 pipe shift amount */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0	36	/* X0 pipe hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0	37	/* X1 pipe hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1	38	/* X0 pipe hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1	39	/* X1 pipe hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW2	40	/* X0 pipe hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW2	41	/* X1 pipe hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW3	42	/* X0 pipe hword 3 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW3	43	/* X1 pipe hword 3 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_LAST 44	/* X0 pipe last hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_LAST 45	/* X1 pipe last hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1_LAST 46	/* X0 pipe last hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1_LAST 47	/* X1 pipe last hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW2_LAST 48	/* X0 pipe last hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW2_LAST 49	/* X1 pipe last hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_PCREL 50	/* X0 pipe PC relative hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_PCREL 51	/* X1 pipe PC relative hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1_PCREL 52	/* X0 pipe PC relative hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1_PCREL 53	/* X1 pipe PC relative hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW2_PCREL 54	/* X0 pipe PC relative hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW2_PCREL 55	/* X1 pipe PC relative hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW3_PCREL 56	/* X0 pipe PC relative hword 3 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW3_PCREL 57	/* X1 pipe PC relative hword 3 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_GOT 64	/* X0 pipe hword 0 GOT offset */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_GOT 65	/* X1 pipe hword 0 GOT offset */
 | |
| ++/* Relocs 66-71 are currently not defined.  */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
 | |
| ++/* Relocs 76-77 are currently not defined.  */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78	/* X0 pipe hword 0 TLS GD offset */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79	/* X1 pipe hword 0 TLS GD offset */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80	/* X0 pipe hword 0 TLS LE offset */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81	/* X1 pipe hword 0 TLS LE offset */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
 | |
| ++/* Relocs 90-91 are currently not defined.  */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92	/* X0 pipe hword 0 TLS IE offset */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93	/* X1 pipe hword 0 TLS IE offset */
 | |
| ++/* Relocs 94-99 are currently not defined.  */
 | |
| ++#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
 | |
| ++#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
 | |
| ++#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
 | |
| ++#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
 | |
| ++/* Relocs 104-105 are currently not defined.  */
 | |
| ++#define R_TILEGX_TLS_DTPMOD64	106	/* 64-bit ID of symbol's module */
 | |
| ++#define R_TILEGX_TLS_DTPOFF64	107	/* 64-bit offset in TLS block */
 | |
| ++#define R_TILEGX_TLS_TPOFF64	108	/* 64-bit offset in static TLS block */
 | |
| ++#define R_TILEGX_TLS_DTPMOD32	109	/* 32-bit ID of symbol's module */
 | |
| ++#define R_TILEGX_TLS_DTPOFF32	110	/* 32-bit offset in TLS block */
 | |
| ++#define R_TILEGX_TLS_TPOFF32	111	/* 32-bit offset in static TLS block */
 | |
| ++#define R_TILEGX_TLS_GD_CALL	112	/* "jal" for TLS GD */
 | |
| ++#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113	/* X0 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114	/* X1 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115	/* Y0 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116	/* Y1 pipe "addi" for TLS GD */
 | |
| ++#define R_TILEGX_TLS_IE_LOAD	117	/* "ld_tls" for TLS IE */
 | |
| ++#define R_TILEGX_IMM8_X0_TLS_ADD 118	/* X0 pipe "addi" for TLS GD/IE */
 | |
| ++#define R_TILEGX_IMM8_X1_TLS_ADD 119	/* X1 pipe "addi" for TLS GD/IE */
 | |
| ++#define R_TILEGX_IMM8_Y0_TLS_ADD 120	/* Y0 pipe "addi" for TLS GD/IE */
 | |
| ++#define R_TILEGX_IMM8_Y1_TLS_ADD 121	/* Y1 pipe "addi" for TLS GD/IE */
 | |
| ++
 | |
| ++#define R_TILEGX_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
 | |
| ++#define R_TILEGX_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
 | |
| ++
 | |
| ++#define R_TILEGX_NUM		130
 | |
| ++
 | |
| ++#endif	/* elf.h */
 | |
| +--- a/scripts/mod/mk_elfconfig.c
 | |
| ++++ b/scripts/mod/mk_elfconfig.c
 | |
| +@@ -2,7 +2,11 @@
 | |
| + #include <stdio.h>
 | |
| + #include <stdlib.h>
 | |
| + #include <string.h>
 | |
| ++#ifndef __APPLE__
 | |
| + #include <elf.h>
 | |
| ++#else
 | |
| ++#include "elf.h"
 | |
| ++#endif
 | |
| + 
 | |
| + int
 | |
| + main(int argc, char **argv)
 | |
| +--- a/scripts/mod/modpost.h
 | |
| ++++ b/scripts/mod/modpost.h
 | |
| +@@ -8,7 +8,11 @@
 | |
| + #include <sys/mman.h>
 | |
| + #include <fcntl.h>
 | |
| + #include <unistd.h>
 | |
| ++#if !(defined(__APPLE__) || defined(__CYGWIN__))
 | |
| + #include <elf.h>
 | |
| ++#else
 | |
| ++#include "elf.h"
 | |
| ++#endif
 | |
| + 
 | |
| + #include "elfconfig.h"
 | |
| + 
 | |
| diff --git a/target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch b/target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch
 | |
| new file mode 100644
 | |
| index 0000000000..50a6227148
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/211-darwin-uuid-typedef-clash.patch
 | |
| @@ -0,0 +1,22 @@
 | |
| +From e44fc2af1ddc452b6659d08c16973d65c73b7d0a Mon Sep 17 00:00:00 2001
 | |
| +From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 | |
| +Date: Wed, 5 Feb 2020 18:36:43 +0000
 | |
| +Subject: [PATCH] file2alias: build on macos
 | |
| +
 | |
| +Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 | |
| +---
 | |
| + scripts/mod/file2alias.c | 3 +++
 | |
| + 1 file changed, 3 insertions(+)
 | |
| +
 | |
| +--- a/scripts/mod/file2alias.c
 | |
| ++++ b/scripts/mod/file2alias.c
 | |
| +@@ -38,6 +38,9 @@ typedef struct {
 | |
| + 	__u8 b[16];
 | |
| + } guid_t;
 | |
| + 
 | |
| ++#ifdef __APPLE__
 | |
| ++#define uuid_t compat_uuid_t
 | |
| ++#endif
 | |
| + /* backwards compatibility, don't use in new code */
 | |
| + typedef struct {
 | |
| + 	__u8 b[16];
 | |
| diff --git a/target/linux/generic/hack-5.10/212-tools_portability.patch b/target/linux/generic/hack-5.10/212-tools_portability.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0d8eb6fb9d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/212-tools_portability.patch
 | |
| @@ -0,0 +1,110 @@
 | |
| +From 48232d3d931c95953ce2ddfe7da7bb164aef6a73 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:03:16 +0200
 | |
| +Subject: fix portability of some includes files in tools/ used on the host
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + tools/include/tools/be_byteshift.h |  4 ++++
 | |
| + tools/include/tools/le_byteshift.h |  4 ++++
 | |
| + tools/include/tools/linux_types.h  | 22 ++++++++++++++++++++++
 | |
| + 3 files changed, 30 insertions(+)
 | |
| + create mode 100644 tools/include/tools/linux_types.h
 | |
| +
 | |
| +--- a/tools/include/tools/be_byteshift.h
 | |
| ++++ b/tools/include/tools/be_byteshift.h
 | |
| +@@ -2,6 +2,10 @@
 | |
| + #ifndef _TOOLS_BE_BYTESHIFT_H
 | |
| + #define _TOOLS_BE_BYTESHIFT_H
 | |
| + 
 | |
| ++#ifndef __linux__
 | |
| ++#include "linux_types.h"
 | |
| ++#endif
 | |
| ++
 | |
| + #include <stdint.h>
 | |
| + 
 | |
| + static inline uint16_t __get_unaligned_be16(const uint8_t *p)
 | |
| +--- a/tools/include/tools/le_byteshift.h
 | |
| ++++ b/tools/include/tools/le_byteshift.h
 | |
| +@@ -2,6 +2,10 @@
 | |
| + #ifndef _TOOLS_LE_BYTESHIFT_H
 | |
| + #define _TOOLS_LE_BYTESHIFT_H
 | |
| + 
 | |
| ++#ifndef __linux__
 | |
| ++#include "linux_types.h"
 | |
| ++#endif
 | |
| ++
 | |
| + #include <stdint.h>
 | |
| + 
 | |
| + static inline uint16_t __get_unaligned_le16(const uint8_t *p)
 | |
| +--- /dev/null
 | |
| ++++ b/tools/include/tools/linux_types.h
 | |
| +@@ -0,0 +1,26 @@
 | |
| ++#ifndef __LINUX_TYPES_H
 | |
| ++#define __LINUX_TYPES_H
 | |
| ++
 | |
| ++#include <stdint.h>
 | |
| ++
 | |
| ++typedef int8_t __s8;
 | |
| ++typedef uint8_t __u8;
 | |
| ++typedef uint8_t __be8;
 | |
| ++typedef uint8_t __le8;
 | |
| ++
 | |
| ++typedef int16_t __s16;
 | |
| ++typedef uint16_t __u16;
 | |
| ++typedef uint16_t __be16;
 | |
| ++typedef uint16_t __le16;
 | |
| ++
 | |
| ++typedef int32_t __s32;
 | |
| ++typedef uint32_t __u32;
 | |
| ++typedef uint32_t __be32;
 | |
| ++typedef uint32_t __le32;
 | |
| ++
 | |
| ++typedef int64_t __s64;
 | |
| ++typedef uint64_t __u64;
 | |
| ++typedef uint64_t __be64;
 | |
| ++typedef uint64_t __le64;
 | |
| ++
 | |
| ++#endif
 | |
| +--- a/tools/include/linux/types.h
 | |
| ++++ b/tools/include/linux/types.h
 | |
| +@@ -7,8 +7,12 @@
 | |
| + #include <stdint.h>
 | |
| + 
 | |
| + #define __SANE_USERSPACE_TYPES__	/* For PPC64, to get LL64 types */
 | |
| ++#ifndef __linux__
 | |
| ++#include <tools/linux_types.h>
 | |
| ++#else
 | |
| + #include <asm/types.h>
 | |
| + #include <asm/posix_types.h>
 | |
| ++#endif
 | |
| + 
 | |
| + struct page;
 | |
| + struct kmem_cache;
 | |
| +--- a/tools/perf/pmu-events/jevents.c
 | |
| ++++ b/tools/perf/pmu-events/jevents.c
 | |
| +@@ -1,4 +1,6 @@
 | |
| ++#ifdef __linux__
 | |
| + #define  _XOPEN_SOURCE 500	/* needed for nftw() */
 | |
| ++#endif
 | |
| + #define  _GNU_SOURCE		/* needed for asprintf() */
 | |
| + 
 | |
| + /* Parse event JSON files */
 | |
| +@@ -35,6 +37,7 @@
 | |
| + #include <stdlib.h>
 | |
| + #include <errno.h>
 | |
| + #include <string.h>
 | |
| ++#include <strings.h>
 | |
| + #include <ctype.h>
 | |
| + #include <unistd.h>
 | |
| + #include <stdarg.h>
 | |
| +--- a/tools/perf/pmu-events/json.c
 | |
| ++++ b/tools/perf/pmu-events/json.c
 | |
| +@@ -38,7 +38,6 @@
 | |
| + #include <unistd.h>
 | |
| + #include "jsmn.h"
 | |
| + #include "json.h"
 | |
| +-#include <linux/kernel.h>
 | |
| + 
 | |
| + 
 | |
| + static char *mapfile(const char *fn, size_t *size)
 | |
| diff --git a/target/linux/generic/hack-5.10/214-spidev_h_portability.patch b/target/linux/generic/hack-5.10/214-spidev_h_portability.patch
 | |
| new file mode 100644
 | |
| index 0000000000..506d50ad4d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/214-spidev_h_portability.patch
 | |
| @@ -0,0 +1,24 @@
 | |
| +From be9be95ff10e16a5b4ad36f903978d0cc5747024 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:04:08 +0200
 | |
| +Subject: kernel: fix linux/spi/spidev.h portability issues with musl
 | |
| +
 | |
| +Felix will try to get this define included into musl
 | |
| +
 | |
| +lede-commit: 795e7cf60de19e7a076a46874fab7bb88b43bbff
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/uapi/linux/spi/spidev.h | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/include/uapi/linux/spi/spidev.h
 | |
| ++++ b/include/uapi/linux/spi/spidev.h
 | |
| +@@ -121,7 +121,7 @@ struct spi_ioc_transfer {
 | |
| + 
 | |
| + /* not all platforms use <asm-generic/ioctl.h> or _IOC_TYPECHECK() ... */
 | |
| + #define SPI_MSGSIZE(N) \
 | |
| +-	((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << _IOC_SIZEBITS)) \
 | |
| ++	((((N)*(sizeof (struct spi_ioc_transfer))) < (1 << 13)) \
 | |
| + 		? ((N)*(sizeof (struct spi_ioc_transfer))) : 0)
 | |
| + #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
 | |
| + 
 | |
| diff --git a/target/linux/generic/hack-5.10/220-gc_sections.patch b/target/linux/generic/hack-5.10/220-gc_sections.patch
 | |
| new file mode 100644
 | |
| index 0000000000..810c5aecf5
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/220-gc_sections.patch
 | |
| @@ -0,0 +1,120 @@
 | |
| +From e3d8676f5722b7622685581e06e8f53e6138e3ab Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sat, 15 Jul 2017 23:42:36 +0200
 | |
| +Subject: use -ffunction-sections, -fdata-sections and --gc-sections
 | |
| +
 | |
| +In combination with kernel symbol export stripping this significantly reduces
 | |
| +the kernel image size. Used on both ARM and MIPS architectures.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 | |
| +Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 | |
| +---
 | |
| +--- a/arch/arm/Kconfig
 | |
| ++++ b/arch/arm/Kconfig
 | |
| +@@ -113,6 +113,7 @@ config ARM
 | |
| + 	select HAVE_UID16
 | |
| + 	select HAVE_VIRT_CPU_ACCOUNTING_GEN
 | |
| + 	select IRQ_FORCED_THREADING
 | |
| ++	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION
 | |
| + 	select MODULES_USE_ELF_REL
 | |
| + 	select NEED_DMA_MAP_STATE
 | |
| + 	select OF_EARLY_FLATTREE if OF
 | |
| +--- a/arch/arm/boot/compressed/Makefile
 | |
| ++++ b/arch/arm/boot/compressed/Makefile
 | |
| +@@ -98,6 +98,7 @@ $(foreach o, $(libfdt_objs) atags_to_fdt
 | |
| + ifdef building_out_of_srctree
 | |
| + $(shell rm -f $(addprefix $(obj)/, fdt_rw.c fdt_ro.c fdt_wip.c fdt.c))
 | |
| + endif
 | |
| ++KBUILD_CFLAGS_KERNEL := $(patsubst -f%-sections,,$(KBUILD_CFLAGS_KERNEL))
 | |
| + 
 | |
| + targets       := vmlinux vmlinux.lds piggy_data piggy.o \
 | |
| + 		 lib1funcs.o ashldi3.o bswapsdi2.o \
 | |
| +--- a/arch/arm/kernel/vmlinux.lds.S
 | |
| ++++ b/arch/arm/kernel/vmlinux.lds.S
 | |
| +@@ -100,24 +100,24 @@ SECTIONS
 | |
| + 	}
 | |
| + 	.init.arch.info : {
 | |
| + 		__arch_info_begin = .;
 | |
| +-		*(.arch.info.init)
 | |
| ++		KEEP(*(.arch.info.init))
 | |
| + 		__arch_info_end = .;
 | |
| + 	}
 | |
| + 	.init.tagtable : {
 | |
| + 		__tagtable_begin = .;
 | |
| +-		*(.taglist.init)
 | |
| ++		KEEP(*(.taglist.init))
 | |
| + 		__tagtable_end = .;
 | |
| + 	}
 | |
| + #ifdef CONFIG_SMP_ON_UP
 | |
| + 	.init.smpalt : {
 | |
| + 		__smpalt_begin = .;
 | |
| +-		*(.alt.smp.init)
 | |
| ++		KEEP(*(.alt.smp.init))
 | |
| + 		__smpalt_end = .;
 | |
| + 	}
 | |
| + #endif
 | |
| + 	.init.pv_table : {
 | |
| + 		__pv_table_begin = .;
 | |
| +-		*(.pv_table)
 | |
| ++		KEEP(*(.pv_table))
 | |
| + 		__pv_table_end = .;
 | |
| + 	}
 | |
| + 
 | |
| +--- a/arch/arm/include/asm/vmlinux.lds.h
 | |
| ++++ b/arch/arm/include/asm/vmlinux.lds.h
 | |
| +@@ -23,19 +23,19 @@
 | |
| + #define ARM_MMU_DISCARD(x)
 | |
| + #else
 | |
| + #define ARM_MMU_KEEP(x)
 | |
| +-#define ARM_MMU_DISCARD(x)	x
 | |
| ++#define ARM_MMU_DISCARD(x)	KEEP(x)
 | |
| + #endif
 | |
| + 
 | |
| + #define PROC_INFO							\
 | |
| + 		. = ALIGN(4);						\
 | |
| + 		__proc_info_begin = .;					\
 | |
| +-		*(.proc.info.init)					\
 | |
| ++		KEEP(*(.proc.info.init))				\
 | |
| + 		__proc_info_end = .;
 | |
| + 
 | |
| + #define IDMAP_TEXT							\
 | |
| + 		ALIGN_FUNCTION();					\
 | |
| + 		__idmap_text_start = .;					\
 | |
| +-		*(.idmap.text)						\
 | |
| ++		KEEP(*(.idmap.text))					\
 | |
| + 		__idmap_text_end = .;					\
 | |
| + 
 | |
| + #define ARM_DISCARD							\
 | |
| +@@ -96,12 +96,12 @@
 | |
| + 	. = ALIGN(8);							\
 | |
| + 	.ARM.unwind_idx : {						\
 | |
| + 		__start_unwind_idx = .;					\
 | |
| +-		*(.ARM.exidx*)						\
 | |
| ++		KEEP(*(.ARM.exidx*))					\
 | |
| + 		__stop_unwind_idx = .;					\
 | |
| + 	}								\
 | |
| + 	.ARM.unwind_tab : {						\
 | |
| + 		__start_unwind_tab = .;					\
 | |
| +-		*(.ARM.extab*)						\
 | |
| ++		KEEP(*(.ARM.extab*))					\
 | |
| + 		__stop_unwind_tab = .;					\
 | |
| + 	}
 | |
| + 
 | |
| +@@ -112,14 +112,14 @@
 | |
| + #define ARM_VECTORS							\
 | |
| + 	__vectors_start = .;						\
 | |
| + 	.vectors 0xffff0000 : AT(__vectors_start) {			\
 | |
| +-		*(.vectors)						\
 | |
| ++		KEEP(*(.vectors))					\
 | |
| + 	}								\
 | |
| + 	. = __vectors_start + SIZEOF(.vectors);				\
 | |
| + 	__vectors_end = .;						\
 | |
| + 									\
 | |
| + 	__stubs_start = .;						\
 | |
| + 	.stubs ADDR(.vectors) + 0x1000 : AT(__stubs_start) {		\
 | |
| +-		*(.stubs)						\
 | |
| ++		KEEP(*(.stubs))						\
 | |
| + 	}								\
 | |
| + 	. = __stubs_start + SIZEOF(.stubs);				\
 | |
| + 	__stubs_end = .;						\
 | |
| diff --git a/target/linux/generic/hack-5.10/221-module_exports.patch b/target/linux/generic/hack-5.10/221-module_exports.patch
 | |
| new file mode 100644
 | |
| index 0000000000..07885408f1
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/221-module_exports.patch
 | |
| @@ -0,0 +1,102 @@
 | |
| +From b14784e7883390c20ed3ff904892255404a5914b Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:05:53 +0200
 | |
| +Subject: add an optional config option for stripping all unnecessary symbol exports from the kernel image
 | |
| +
 | |
| +lede-commit: bb5a40c64b7c4f4848509fa0a6625055fc9e66cc
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/asm-generic/vmlinux.lds.h | 18 +++++++++++++++---
 | |
| + include/linux/export.h            |  9 ++++++++-
 | |
| + scripts/Makefile.build            |  2 +-
 | |
| + 3 files changed, 24 insertions(+), 5 deletions(-)
 | |
| +
 | |
| +--- a/include/asm-generic/vmlinux.lds.h
 | |
| ++++ b/include/asm-generic/vmlinux.lds.h
 | |
| +@@ -81,6 +81,16 @@
 | |
| + #define RO_EXCEPTION_TABLE
 | |
| + #endif
 | |
| + 
 | |
| ++#ifndef SYMTAB_KEEP
 | |
| ++#define SYMTAB_KEEP KEEP(*(SORT(___ksymtab+*)))
 | |
| ++#define SYMTAB_KEEP_GPL KEEP(*(SORT(___ksymtab_gpl+*)))
 | |
| ++#endif
 | |
| ++
 | |
| ++#ifndef SYMTAB_DISCARD
 | |
| ++#define SYMTAB_DISCARD
 | |
| ++#define SYMTAB_DISCARD_GPL
 | |
| ++#endif
 | |
| ++
 | |
| + /* Align . to a 8 byte boundary equals to maximum function alignment. */
 | |
| + #define ALIGN_FUNCTION()  . = ALIGN(8)
 | |
| + 
 | |
| +@@ -473,14 +483,14 @@
 | |
| + 	/* Kernel symbol table: Normal symbols */			\
 | |
| + 	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
 | |
| + 		__start___ksymtab = .;					\
 | |
| +-		KEEP(*(SORT(___ksymtab+*)))				\
 | |
| ++		SYMTAB_KEEP						\
 | |
| + 		__stop___ksymtab = .;					\
 | |
| + 	}								\
 | |
| + 									\
 | |
| + 	/* Kernel symbol table: GPL-only symbols */			\
 | |
| + 	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\
 | |
| + 		__start___ksymtab_gpl = .;				\
 | |
| +-		KEEP(*(SORT(___ksymtab_gpl+*)))				\
 | |
| ++		SYMTAB_KEEP_GPL						\
 | |
| + 		__stop___ksymtab_gpl = .;				\
 | |
| + 	}								\
 | |
| + 									\
 | |
| +@@ -542,7 +552,7 @@
 | |
| + 									\
 | |
| + 	/* Kernel symbol table: strings */				\
 | |
| +         __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
 | |
| +-		*(__ksymtab_strings)					\
 | |
| ++		*(__ksymtab_strings+*)					\
 | |
| + 	}								\
 | |
| + 									\
 | |
| + 	/* __*init sections */						\
 | |
| +@@ -1017,6 +1027,8 @@
 | |
| + 
 | |
| + #define COMMON_DISCARDS							\
 | |
| + 	SANITIZER_DISCARDS						\
 | |
| ++	SYMTAB_DISCARD							\
 | |
| ++	SYMTAB_DISCARD_GPL						\
 | |
| + 	*(.discard)							\
 | |
| + 	*(.discard.*)							\
 | |
| + 	*(.modinfo)							\
 | |
| +--- a/include/linux/export.h
 | |
| ++++ b/include/linux/export.h
 | |
| +@@ -82,6 +82,12 @@ struct kernel_symbol {
 | |
| + 
 | |
| + #else
 | |
| + 
 | |
| ++#ifdef MODULE
 | |
| ++#define __EXPORT_SUFFIX(sym)
 | |
| ++#else
 | |
| ++#define __EXPORT_SUFFIX(sym) "+" #sym
 | |
| ++#endif
 | |
| ++
 | |
| + /*
 | |
| +  * For every exported symbol, do the following:
 | |
| +  *
 | |
| +@@ -99,7 +105,7 @@ struct kernel_symbol {
 | |
| + 	extern const char __kstrtab_##sym[];					\
 | |
| + 	extern const char __kstrtabns_##sym[];					\
 | |
| + 	__CRC_SYMBOL(sym, sec);							\
 | |
| +-	asm("	.section \"__ksymtab_strings\",\"aMS\",%progbits,1	\n"	\
 | |
| ++	asm("	.section \"__ksymtab_strings" __EXPORT_SUFFIX(sym) "\",\"aMS\",%progbits,1	\n"	\
 | |
| + 	    "__kstrtab_" #sym ":					\n"	\
 | |
| + 	    "	.asciz 	\"" #sym "\"					\n"	\
 | |
| + 	    "__kstrtabns_" #sym ":					\n"	\
 | |
| +--- a/scripts/Makefile.build
 | |
| ++++ b/scripts/Makefile.build
 | |
| +@@ -366,7 +366,7 @@ targets += $(lib-y) $(always-y) $(MAKECM
 | |
| + # Linker scripts preprocessor (.lds.S -> .lds)
 | |
| + # ---------------------------------------------------------------------------
 | |
| + quiet_cmd_cpp_lds_S = LDS     $@
 | |
| +-      cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -U$(ARCH) \
 | |
| ++      cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -U$(ARCH) \
 | |
| + 	                     -D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
 | |
| + 
 | |
| + $(obj)/%.lds: $(src)/%.lds.S FORCE
 | |
| diff --git a/target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch b/target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch
 | |
| new file mode 100644
 | |
| index 0000000000..906527faf9
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/230-openwrt_lzma_options.patch
 | |
| @@ -0,0 +1,34 @@
 | |
| +From b3d00b452467f621317953d9e4c6f9ae8dcfd271 Mon Sep 17 00:00:00 2001
 | |
| +From: Imre Kaloz <kaloz@openwrt.org>
 | |
| +Date: Fri, 7 Jul 2017 17:06:55 +0200
 | |
| +Subject: use the openwrt lzma options for now
 | |
| +
 | |
| +lede-commit: 548de949f392049420a6a1feeef118b30ab8ea8c
 | |
| +Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
 | |
| +---
 | |
| + lib/decompress.c              |  1 +
 | |
| + scripts/Makefile.lib          |  2 +-
 | |
| + usr/gen_initramfs_list.sh | 10 +++++-----
 | |
| + 3 files changed, 7 insertions(+), 6 deletions(-)
 | |
| +
 | |
| +--- a/lib/decompress.c
 | |
| ++++ b/lib/decompress.c
 | |
| +@@ -53,6 +53,7 @@ static const struct compress_format comp
 | |
| + 	{ {0x1f, 0x9e}, "gzip", gunzip },
 | |
| + 	{ {0x42, 0x5a}, "bzip2", bunzip2 },
 | |
| + 	{ {0x5d, 0x00}, "lzma", unlzma },
 | |
| ++	{ {0x6d, 0x00}, "lzma-openwrt", unlzma },
 | |
| + 	{ {0xfd, 0x37}, "xz", unxz },
 | |
| + 	{ {0x89, 0x4c}, "lzo", unlzo },
 | |
| + 	{ {0x02, 0x21}, "lz4", unlz4 },
 | |
| +--- a/scripts/Makefile.lib
 | |
| ++++ b/scripts/Makefile.lib
 | |
| +@@ -370,7 +370,7 @@ quiet_cmd_bzip2 = BZIP2   $@
 | |
| + # ---------------------------------------------------------------------------
 | |
| + 
 | |
| + quiet_cmd_lzma = LZMA    $@
 | |
| +-      cmd_lzma = { cat $(real-prereqs) | $(LZMA) -9; $(size_append); } > $@
 | |
| ++      cmd_lzma = { cat $(real-prereqs) | $(LZMA) e -d20 -lc1 -lp2 -pb2 -eos -si -so; $(size_append); } > $@
 | |
| + 
 | |
| + quiet_cmd_lzo = LZO     $@
 | |
| +       cmd_lzo = { cat $(real-prereqs) | $(KLZOP) -9; $(size_append); } > $@
 | |
| diff --git a/target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch b/target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2c74298dfe
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/249-udp-tunnel-selection.patch
 | |
| @@ -0,0 +1,11 @@
 | |
| +--- a/net/ipv4/Kconfig
 | |
| ++++ b/net/ipv4/Kconfig
 | |
| +@@ -315,7 +315,7 @@ config NET_IPVTI
 | |
| + 	  on top.
 | |
| + 
 | |
| + config NET_UDP_TUNNEL
 | |
| +-	tristate
 | |
| ++	tristate "IP: UDP tunneling support"
 | |
| + 	select NET_IP_TUNNEL
 | |
| + 	default n
 | |
| + 
 | |
| diff --git a/target/linux/generic/hack-5.10/250-netfilter_depends.patch b/target/linux/generic/hack-5.10/250-netfilter_depends.patch
 | |
| new file mode 100644
 | |
| index 0000000000..b27b440157
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/250-netfilter_depends.patch
 | |
| @@ -0,0 +1,27 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: hack: net: remove bogus netfilter dependencies
 | |
| +
 | |
| +lede-commit: 589d2a377dee27d206fc3725325309cf649e4df6
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + net/netfilter/Kconfig | 2 --
 | |
| + 1 file changed, 2 deletions(-)
 | |
| +
 | |
| +--- a/net/netfilter/Kconfig
 | |
| ++++ b/net/netfilter/Kconfig
 | |
| +@@ -228,7 +228,6 @@ config NF_CONNTRACK_FTP
 | |
| + 
 | |
| + config NF_CONNTRACK_H323
 | |
| + 	tristate "H.323 protocol support"
 | |
| +-	depends on IPV6 || IPV6=n
 | |
| + 	depends on NETFILTER_ADVANCED
 | |
| + 	help
 | |
| + 	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most
 | |
| +@@ -1072,7 +1071,6 @@ config NETFILTER_XT_TARGET_SECMARK
 | |
| + 
 | |
| + config NETFILTER_XT_TARGET_TCPMSS
 | |
| + 	tristate '"TCPMSS" target support'
 | |
| +-	depends on IPV6 || IPV6=n
 | |
| + 	default m if NETFILTER_ADVANCED=n
 | |
| + 	help
 | |
| + 	  This option adds a `TCPMSS' target, which allows you to alter the
 | |
| diff --git a/target/linux/generic/hack-5.10/251-kconfig.patch b/target/linux/generic/hack-5.10/251-kconfig.patch
 | |
| new file mode 100644
 | |
| index 0000000000..f80561c8e6
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/251-kconfig.patch
 | |
| @@ -0,0 +1,199 @@
 | |
| +From da3c50704f14132f4adf80d48e9a4cd5d46e54c9 Mon Sep 17 00:00:00 2001
 | |
| +From: John Crispin <john@phrozen.org>
 | |
| +Date: Fri, 7 Jul 2017 17:09:21 +0200
 | |
| +Subject: kconfig: owrt specifc dependencies
 | |
| +
 | |
| +Signed-off-by: John Crispin <john@phrozen.org>
 | |
| +---
 | |
| + crypto/Kconfig        | 10 +++++-----
 | |
| + drivers/bcma/Kconfig  |  1 +
 | |
| + drivers/ssb/Kconfig   |  3 ++-
 | |
| + lib/Kconfig           |  8 ++++----
 | |
| + net/netfilter/Kconfig |  2 +-
 | |
| + net/wireless/Kconfig  | 17 ++++++++++-------
 | |
| + sound/core/Kconfig    |  4 ++--
 | |
| + 7 files changed, 25 insertions(+), 20 deletions(-)
 | |
| +
 | |
| +--- a/crypto/Kconfig
 | |
| ++++ b/crypto/Kconfig
 | |
| +@@ -33,7 +33,7 @@ config CRYPTO_FIPS
 | |
| + 	  this is.
 | |
| + 
 | |
| + config CRYPTO_ALGAPI
 | |
| +-	tristate
 | |
| ++	tristate "ALGAPI"
 | |
| + 	select CRYPTO_ALGAPI2
 | |
| + 	help
 | |
| + 	  This option provides the API for cryptographic algorithms.
 | |
| +@@ -42,7 +42,7 @@ config CRYPTO_ALGAPI2
 | |
| + 	tristate
 | |
| + 
 | |
| + config CRYPTO_AEAD
 | |
| +-	tristate
 | |
| ++	tristate "AEAD"
 | |
| + 	select CRYPTO_AEAD2
 | |
| + 	select CRYPTO_ALGAPI
 | |
| + 
 | |
| +@@ -53,7 +53,7 @@ config CRYPTO_AEAD2
 | |
| + 	select CRYPTO_RNG2
 | |
| + 
 | |
| + config CRYPTO_SKCIPHER
 | |
| +-	tristate
 | |
| ++	tristate "SKCIPHER"
 | |
| + 	select CRYPTO_SKCIPHER2
 | |
| + 	select CRYPTO_ALGAPI
 | |
| + 
 | |
| +@@ -63,7 +63,7 @@ config CRYPTO_SKCIPHER2
 | |
| + 	select CRYPTO_RNG2
 | |
| + 
 | |
| + config CRYPTO_HASH
 | |
| +-	tristate
 | |
| ++	tristate "HASH"
 | |
| + 	select CRYPTO_HASH2
 | |
| + 	select CRYPTO_ALGAPI
 | |
| + 
 | |
| +@@ -72,7 +72,7 @@ config CRYPTO_HASH2
 | |
| + 	select CRYPTO_ALGAPI2
 | |
| + 
 | |
| + config CRYPTO_RNG
 | |
| +-	tristate
 | |
| ++	tristate "RNG"
 | |
| + 	select CRYPTO_RNG2
 | |
| + 	select CRYPTO_ALGAPI
 | |
| + 
 | |
| +--- a/drivers/bcma/Kconfig
 | |
| ++++ b/drivers/bcma/Kconfig
 | |
| +@@ -16,6 +16,7 @@ if BCMA
 | |
| + # Support for Block-I/O. SELECT this from the driver that needs it.
 | |
| + config BCMA_BLOCKIO
 | |
| + 	bool
 | |
| ++	default y
 | |
| + 
 | |
| + config BCMA_HOST_PCI_POSSIBLE
 | |
| + 	bool
 | |
| +--- a/drivers/ssb/Kconfig
 | |
| ++++ b/drivers/ssb/Kconfig
 | |
| +@@ -29,6 +29,7 @@ config SSB_SPROM
 | |
| + config SSB_BLOCKIO
 | |
| + 	bool
 | |
| + 	depends on SSB
 | |
| ++	default y
 | |
| + 
 | |
| + config SSB_PCIHOST_POSSIBLE
 | |
| + 	bool
 | |
| +@@ -49,7 +50,7 @@ config SSB_PCIHOST
 | |
| + config SSB_B43_PCI_BRIDGE
 | |
| + 	bool
 | |
| + 	depends on SSB_PCIHOST
 | |
| +-	default n
 | |
| ++	default y
 | |
| + 
 | |
| + config SSB_PCMCIAHOST_POSSIBLE
 | |
| + 	bool
 | |
| +--- a/lib/Kconfig
 | |
| ++++ b/lib/Kconfig
 | |
| +@@ -419,16 +419,16 @@ config BCH_CONST_T
 | |
| + # Textsearch support is select'ed if needed
 | |
| + #
 | |
| + config TEXTSEARCH
 | |
| +-	bool
 | |
| ++	bool "Textsearch support"
 | |
| + 
 | |
| + config TEXTSEARCH_KMP
 | |
| +-	tristate
 | |
| ++	tristate "Textsearch KMP"
 | |
| + 
 | |
| + config TEXTSEARCH_BM
 | |
| +-	tristate
 | |
| ++	tristate "Textsearch BM"
 | |
| + 
 | |
| + config TEXTSEARCH_FSM
 | |
| +-	tristate
 | |
| ++	tristate "Textsearch FSM"
 | |
| + 
 | |
| + config BTREE
 | |
| + 	bool
 | |
| +--- a/net/netfilter/Kconfig
 | |
| ++++ b/net/netfilter/Kconfig
 | |
| +@@ -11,7 +11,7 @@ config NETFILTER_INGRESS
 | |
| + 	  infrastructure.
 | |
| + 
 | |
| + config NETFILTER_NETLINK
 | |
| +-	tristate
 | |
| ++	tristate "Netfilter NFNETLINK interface"
 | |
| + 
 | |
| + config NETFILTER_FAMILY_BRIDGE
 | |
| + 	bool
 | |
| +--- a/net/wireless/Kconfig
 | |
| ++++ b/net/wireless/Kconfig
 | |
| +@@ -1,6 +1,6 @@
 | |
| + # SPDX-License-Identifier: GPL-2.0-only
 | |
| + config WIRELESS_EXT
 | |
| +-	bool
 | |
| ++	bool "Wireless extensions"
 | |
| + 
 | |
| + config WEXT_CORE
 | |
| + 	def_bool y
 | |
| +@@ -12,10 +12,10 @@ config WEXT_PROC
 | |
| + 	depends on WEXT_CORE
 | |
| + 
 | |
| + config WEXT_SPY
 | |
| +-	bool
 | |
| ++	bool "WEXT_SPY"
 | |
| + 
 | |
| + config WEXT_PRIV
 | |
| +-	bool
 | |
| ++	bool "WEXT_PRIV"
 | |
| + 
 | |
| + config CFG80211
 | |
| + 	tristate "cfg80211 - wireless configuration API"
 | |
| +@@ -204,7 +204,7 @@ config CFG80211_WEXT_EXPORT
 | |
| + endif # CFG80211
 | |
| + 
 | |
| + config LIB80211
 | |
| +-	tristate
 | |
| ++	tristate "LIB80211"
 | |
| + 	default n
 | |
| + 	help
 | |
| + 	  This options enables a library of common routines used
 | |
| +@@ -213,17 +213,17 @@ config LIB80211
 | |
| + 	  Drivers should select this themselves if needed.
 | |
| + 
 | |
| + config LIB80211_CRYPT_WEP
 | |
| +-	tristate
 | |
| ++	tristate "LIB80211_CRYPT_WEP"
 | |
| + 	select CRYPTO_LIB_ARC4
 | |
| + 
 | |
| + config LIB80211_CRYPT_CCMP
 | |
| +-	tristate
 | |
| ++	tristate "LIB80211_CRYPT_CCMP"
 | |
| + 	select CRYPTO
 | |
| + 	select CRYPTO_AES
 | |
| + 	select CRYPTO_CCM
 | |
| + 
 | |
| + config LIB80211_CRYPT_TKIP
 | |
| +-	tristate
 | |
| ++	tristate "LIB80211_CRYPT_TKIP"
 | |
| + 	select CRYPTO_LIB_ARC4
 | |
| + 
 | |
| + config LIB80211_DEBUG
 | |
| +--- a/sound/core/Kconfig
 | |
| ++++ b/sound/core/Kconfig
 | |
| +@@ -17,7 +17,7 @@ config SND_DMAENGINE_PCM
 | |
| + 	tristate
 | |
| + 
 | |
| + config SND_HWDEP
 | |
| +-	tristate
 | |
| ++	tristate "Sound hardware support"
 | |
| + 
 | |
| + config SND_SEQ_DEVICE
 | |
| + 	tristate
 | |
| +@@ -27,7 +27,7 @@ config SND_RAWMIDI
 | |
| + 	select SND_SEQ_DEVICE if SND_SEQUENCER != n
 | |
| + 
 | |
| + config SND_COMPRESS_OFFLOAD
 | |
| +-	tristate
 | |
| ++	tristate "Compression offloading support"
 | |
| + 
 | |
| + config SND_JACK
 | |
| + 	bool
 | |
| diff --git a/target/linux/generic/hack-5.10/259-regmap_dynamic.patch b/target/linux/generic/hack-5.10/259-regmap_dynamic.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e5159cb000
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/259-regmap_dynamic.patch
 | |
| @@ -0,0 +1,135 @@
 | |
| +From 811d9e2268a62b830cfe93cd8bc929afcb8b198b Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sat, 15 Jul 2017 21:12:38 +0200
 | |
| +Subject: kernel: move regmap bloat out of the kernel image if it is only being used in modules
 | |
| +
 | |
| +lede-commit: 96f39119815028073583e4fca3a9c5fe9141e998
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/base/regmap/Kconfig  | 15 ++++++++++-----
 | |
| + drivers/base/regmap/Makefile | 12 ++++++++----
 | |
| + drivers/base/regmap/regmap.c |  3 +++
 | |
| + include/linux/regmap.h       |  2 +-
 | |
| + 4 files changed, 22 insertions(+), 10 deletions(-)
 | |
| +
 | |
| +--- a/drivers/base/regmap/Kconfig
 | |
| ++++ b/drivers/base/regmap/Kconfig
 | |
| +@@ -4,9 +4,8 @@
 | |
| + # subsystems should select the appropriate symbols.
 | |
| + 
 | |
| + config REGMAP
 | |
| +-	default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM)
 | |
| + 	select IRQ_DOMAIN if REGMAP_IRQ
 | |
| +-	bool
 | |
| ++	tristate
 | |
| + 
 | |
| + config REGCACHE_COMPRESSED
 | |
| + 	select LZO_COMPRESS
 | |
| +@@ -14,46 +13,59 @@ config REGCACHE_COMPRESSED
 | |
| + 	bool
 | |
| + 
 | |
| + config REGMAP_AC97
 | |
| ++	select REGMAP
 | |
| + 	tristate
 | |
| + 
 | |
| + config REGMAP_I2C
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on I2C
 | |
| + 
 | |
| + config REGMAP_SLIMBUS
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on SLIMBUS
 | |
| + 
 | |
| + config REGMAP_SPI
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| ++	depends on SPI_MASTER
 | |
| + 	depends on SPI
 | |
| + 
 | |
| + config REGMAP_SPMI
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on SPMI
 | |
| + 
 | |
| + config REGMAP_W1
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on W1
 | |
| + 
 | |
| + config REGMAP_MMIO
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 
 | |
| + config REGMAP_IRQ
 | |
| + 	bool
 | |
| ++	select REGMAP
 | |
| + 
 | |
| + config REGMAP_SOUNDWIRE
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on SOUNDWIRE
 | |
| + 
 | |
| + config REGMAP_SCCB
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on I2C
 | |
| + 
 | |
| + config REGMAP_I3C
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on I3C
 | |
| + 
 | |
| + config REGMAP_SPI_AVMM
 | |
| + 	tristate
 | |
| ++	select REGMAP
 | |
| + 	depends on SPI
 | |
| +--- a/drivers/base/regmap/Makefile
 | |
| ++++ b/drivers/base/regmap/Makefile
 | |
| +@@ -2,10 +2,14 @@
 | |
| + # For include/trace/define_trace.h to include trace.h
 | |
| + CFLAGS_regmap.o := -I$(src)
 | |
| + 
 | |
| +-obj-$(CONFIG_REGMAP) += regmap.o regcache.o
 | |
| +-obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-flat.o
 | |
| +-obj-$(CONFIG_REGCACHE_COMPRESSED) += regcache-lzo.o
 | |
| +-obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
 | |
| ++regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-flat.o
 | |
| ++ifdef CONFIG_DEBUG_FS
 | |
| ++regmap-core-objs += regmap-debugfs.o
 | |
| ++endif
 | |
| ++ifdef CONFIG_REGCACHE_COMPRESSED
 | |
| ++regmap-core-objs += regcache-lzo.o
 | |
| ++endif
 | |
| ++obj-$(CONFIG_REGMAP) += regmap-core.o
 | |
| + obj-$(CONFIG_REGMAP_AC97) += regmap-ac97.o
 | |
| + obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
 | |
| + obj-$(CONFIG_REGMAP_SLIMBUS) += regmap-slimbus.o
 | |
| +--- a/drivers/base/regmap/regmap.c
 | |
| ++++ b/drivers/base/regmap/regmap.c
 | |
| +@@ -9,6 +9,7 @@
 | |
| + #include <linux/device.h>
 | |
| + #include <linux/slab.h>
 | |
| + #include <linux/export.h>
 | |
| ++#include <linux/module.h>
 | |
| + #include <linux/mutex.h>
 | |
| + #include <linux/err.h>
 | |
| + #include <linux/property.h>
 | |
| +@@ -3296,3 +3297,5 @@ static int __init regmap_initcall(void)
 | |
| + 	return 0;
 | |
| + }
 | |
| + postcore_initcall(regmap_initcall);
 | |
| ++
 | |
| ++MODULE_LICENSE("GPL");
 | |
| +--- a/include/linux/regmap.h
 | |
| ++++ b/include/linux/regmap.h
 | |
| +@@ -179,7 +179,7 @@ struct reg_sequence {
 | |
| + 	__ret ?: __tmp; \
 | |
| + })
 | |
| + 
 | |
| +-#ifdef CONFIG_REGMAP
 | |
| ++#if IS_REACHABLE(CONFIG_REGMAP)
 | |
| + 
 | |
| + enum regmap_endian {
 | |
| + 	/* Unspecified -> 0 -> Backwards compatible default */
 | |
| diff --git a/target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch b/target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1eab709c46
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/260-crypto_test_dependencies.patch
 | |
| @@ -0,0 +1,52 @@
 | |
| +From fd1799b0bf5efa46dd3e6dfbbf3955564807e508 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:12:51 +0200
 | |
| +Subject: kernel: prevent cryptomgr from pulling in useless extra dependencies for tests that are not run
 | |
| +
 | |
| +Reduces kernel size after LZMA by about 5k on MIPS
 | |
| +
 | |
| +lede-commit: 044c316167e076479a344c59905e5b435b84a77f
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + crypto/Kconfig   | 13 ++++++-------
 | |
| + crypto/algboss.c |  4 ++++
 | |
| + 2 files changed, 10 insertions(+), 7 deletions(-)
 | |
| +
 | |
| +--- a/crypto/Kconfig
 | |
| ++++ b/crypto/Kconfig
 | |
| +@@ -120,13 +120,13 @@ config CRYPTO_MANAGER
 | |
| + 	  cbc(aes).
 | |
| + 
 | |
| + config CRYPTO_MANAGER2
 | |
| +-	def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y)
 | |
| +-	select CRYPTO_AEAD2
 | |
| +-	select CRYPTO_HASH2
 | |
| +-	select CRYPTO_SKCIPHER2
 | |
| +-	select CRYPTO_AKCIPHER2
 | |
| +-	select CRYPTO_KPP2
 | |
| +-	select CRYPTO_ACOMP2
 | |
| ++	def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y && !CRYPTO_MANAGER_DISABLE_TESTS)
 | |
| ++	select CRYPTO_AEAD2 if !CRYPTO_MANAGER_DISABLE_TESTS
 | |
| ++	select CRYPTO_HASH2 if !CRYPTO_MANAGER_DISABLE_TESTS
 | |
| ++	select CRYPTO_SKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
 | |
| ++	select CRYPTO_AKCIPHER2 if !CRYPTO_MANAGER_DISABLE_TESTS
 | |
| ++	select CRYPTO_KPP2 if !CRYPTO_MANAGER_DISABLE_TESTS
 | |
| ++	select CRYPTO_ACOMP2 if !CRYPTO_MANAGER_DISABLE_TESTS
 | |
| + 
 | |
| + config CRYPTO_USER
 | |
| + 	tristate "Userspace cryptographic algorithm configuration"
 | |
| +--- a/crypto/algboss.c
 | |
| ++++ b/crypto/algboss.c
 | |
| +@@ -230,8 +230,12 @@ static int cryptomgr_schedule_test(struc
 | |
| + 	type = alg->cra_flags;
 | |
| + 
 | |
| + 	/* Do not test internal algorithms. */
 | |
| ++#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
 | |
| ++	type |= CRYPTO_ALG_TESTED;
 | |
| ++#else
 | |
| + 	if (type & CRYPTO_ALG_INTERNAL)
 | |
| + 		type |= CRYPTO_ALG_TESTED;
 | |
| ++#endif
 | |
| + 
 | |
| + 	param->type = type;
 | |
| + 
 | |
| diff --git a/target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch b/target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a7668acfad
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/261-lib-arc4-unhide.patch
 | |
| @@ -0,0 +1,15 @@
 | |
| +This makes it possible to select CONFIG_CRYPTO_LIB_ARC4 directly. We 
 | |
| +need this to be able to compile this into the kernel and make use of it 
 | |
| +from backports.
 | |
| +
 | |
| +--- a/lib/crypto/Kconfig
 | |
| ++++ b/lib/crypto/Kconfig
 | |
| +@@ -6,7 +6,7 @@ config CRYPTO_LIB_AES
 | |
| + 	tristate
 | |
| + 
 | |
| + config CRYPTO_LIB_ARC4
 | |
| +-	tristate
 | |
| ++	tristate "ARC4 cipher library"
 | |
| + 
 | |
| + config CRYPTO_ARCH_HAVE_LIB_BLAKE2S
 | |
| + 	tristate
 | |
| diff --git a/target/linux/generic/hack-5.10/280-rfkill-stubs.patch b/target/linux/generic/hack-5.10/280-rfkill-stubs.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2e48aea1cf
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/280-rfkill-stubs.patch
 | |
| @@ -0,0 +1,84 @@
 | |
| +From 236c1acdfef5958010ac9814a9872e0a46fd78ee Mon Sep 17 00:00:00 2001
 | |
| +From: John Crispin <john@phrozen.org>
 | |
| +Date: Fri, 7 Jul 2017 17:13:44 +0200
 | |
| +Subject: rfkill: add fake rfkill support
 | |
| +
 | |
| +allow building of modules depending on RFKILL even if RFKILL is not enabled.
 | |
| +
 | |
| +Signed-off-by: John Crispin <john@phrozen.org>
 | |
| +---
 | |
| + include/linux/rfkill.h |  2 +-
 | |
| + net/Makefile           |  2 +-
 | |
| + net/rfkill/Kconfig     | 14 +++++++++-----
 | |
| + net/rfkill/Makefile    |  2 +-
 | |
| + 4 files changed, 12 insertions(+), 8 deletions(-)
 | |
| +
 | |
| +--- a/include/linux/rfkill.h
 | |
| ++++ b/include/linux/rfkill.h
 | |
| +@@ -64,7 +64,7 @@ struct rfkill_ops {
 | |
| + 	int	(*set_block)(void *data, bool blocked);
 | |
| + };
 | |
| + 
 | |
| +-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
 | |
| ++#if defined(CONFIG_RFKILL_FULL) || defined(CONFIG_RFKILL_FULL_MODULE)
 | |
| + /**
 | |
| +  * rfkill_alloc - Allocate rfkill structure
 | |
| +  * @name: name of the struct -- the string is not copied internally
 | |
| +--- a/net/Makefile
 | |
| ++++ b/net/Makefile
 | |
| +@@ -53,7 +53,7 @@ obj-$(CONFIG_TIPC)		+= tipc/
 | |
| + obj-$(CONFIG_NETLABEL)		+= netlabel/
 | |
| + obj-$(CONFIG_IUCV)		+= iucv/
 | |
| + obj-$(CONFIG_SMC)		+= smc/
 | |
| +-obj-$(CONFIG_RFKILL)		+= rfkill/
 | |
| ++obj-$(CONFIG_RFKILL_FULL)	+= rfkill/
 | |
| + obj-$(CONFIG_NET_9P)		+= 9p/
 | |
| + obj-$(CONFIG_CAIF)		+= caif/
 | |
| + ifneq ($(CONFIG_DCB),)
 | |
| +--- a/net/rfkill/Kconfig
 | |
| ++++ b/net/rfkill/Kconfig
 | |
| +@@ -2,7 +2,11 @@
 | |
| + #
 | |
| + # RF switch subsystem configuration
 | |
| + #
 | |
| +-menuconfig RFKILL
 | |
| ++config RFKILL
 | |
| ++	bool
 | |
| ++	default y
 | |
| ++
 | |
| ++menuconfig RFKILL_FULL
 | |
| + 	tristate "RF switch subsystem support"
 | |
| + 	help
 | |
| + 	  Say Y here if you want to have control over RF switches
 | |
| +@@ -14,19 +18,19 @@ menuconfig RFKILL
 | |
| + # LED trigger support
 | |
| + config RFKILL_LEDS
 | |
| + 	bool
 | |
| +-	depends on RFKILL
 | |
| ++	depends on RFKILL_FULL
 | |
| + 	depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS
 | |
| + 	default y
 | |
| + 
 | |
| + config RFKILL_INPUT
 | |
| + 	bool "RF switch input support" if EXPERT
 | |
| +-	depends on RFKILL
 | |
| ++	depends on RFKILL_FULL
 | |
| + 	depends on INPUT = y || RFKILL = INPUT
 | |
| + 	default y if !EXPERT
 | |
| + 
 | |
| + config RFKILL_GPIO
 | |
| + 	tristate "GPIO RFKILL driver"
 | |
| +-	depends on RFKILL
 | |
| ++	depends on RFKILL_FULL
 | |
| + 	depends on GPIOLIB || COMPILE_TEST
 | |
| + 	default n
 | |
| + 	help
 | |
| +--- a/net/rfkill/Makefile
 | |
| ++++ b/net/rfkill/Makefile
 | |
| +@@ -5,5 +5,5 @@
 | |
| + 
 | |
| + rfkill-y			+= core.o
 | |
| + rfkill-$(CONFIG_RFKILL_INPUT)	+= input.o
 | |
| +-obj-$(CONFIG_RFKILL)		+= rfkill.o
 | |
| ++obj-$(CONFIG_RFKILL_FULL)	+= rfkill.o
 | |
| + obj-$(CONFIG_RFKILL_GPIO)	+= rfkill-gpio.o
 | |
| diff --git a/target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch b/target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch
 | |
| new file mode 100644
 | |
| index 0000000000..fe89de7e08
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/300-MIPS-r4k_cache-use-more-efficient-cache-blast.patch
 | |
| @@ -0,0 +1,64 @@
 | |
| +From: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
 | |
| +Date: Fri, 7 Jun 2013 18:35:22 -0500
 | |
| +Subject: MIPS: r4k_cache: use more efficient cache blast
 | |
| +
 | |
| +Optimize the compiler output for larger cache blast cases that are
 | |
| +common for DMA-based networking.
 | |
| +
 | |
| +Signed-off-by: Ben Menchaca <ben.menchaca@qca.qualcomm.com>
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +--- a/arch/mips/include/asm/r4kcache.h
 | |
| ++++ b/arch/mips/include/asm/r4kcache.h
 | |
| +@@ -296,14 +296,46 @@ static inline void prot##extra##blast_##
 | |
| + 						    unsigned long end)	\
 | |
| + {									\
 | |
| + 	unsigned long lsize = cpu_##desc##_line_size();			\
 | |
| ++	unsigned long lsize_2 = lsize * 2;				\
 | |
| ++	unsigned long lsize_3 = lsize * 3;				\
 | |
| ++	unsigned long lsize_4 = lsize * 4;				\
 | |
| ++	unsigned long lsize_5 = lsize * 5;				\
 | |
| ++	unsigned long lsize_6 = lsize * 6;				\
 | |
| ++	unsigned long lsize_7 = lsize * 7;				\
 | |
| ++	unsigned long lsize_8 = lsize * 8;				\
 | |
| + 	unsigned long addr = start & ~(lsize - 1);			\
 | |
| +-	unsigned long aend = (end - 1) & ~(lsize - 1);			\
 | |
| ++	unsigned long aend = (end + lsize - 1) & ~(lsize - 1);		\
 | |
| ++	int lines = (aend - addr) / lsize;				\
 | |
| + 									\
 | |
| +-	while (1) {							\
 | |
| ++	while (lines >= 8) {						\
 | |
| ++		prot##cache_op(hitop, addr);				\
 | |
| ++		prot##cache_op(hitop, addr + lsize);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_2);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_3);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_4);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_5);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_6);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_7);			\
 | |
| ++		addr += lsize_8;					\
 | |
| ++		lines -= 8;						\
 | |
| ++	}								\
 | |
| ++									\
 | |
| ++	if (lines & 0x4) {						\
 | |
| ++		prot##cache_op(hitop, addr);				\
 | |
| ++		prot##cache_op(hitop, addr + lsize);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_2);			\
 | |
| ++		prot##cache_op(hitop, addr + lsize_3);			\
 | |
| ++		addr += lsize_4;					\
 | |
| ++	}								\
 | |
| ++									\
 | |
| ++	if (lines & 0x2) {						\
 | |
| ++		prot##cache_op(hitop, addr);				\
 | |
| ++		prot##cache_op(hitop, addr + lsize);			\
 | |
| ++		addr += lsize_2;					\
 | |
| ++	}								\
 | |
| ++									\
 | |
| ++	if (lines & 0x1) {						\
 | |
| + 		prot##cache_op(hitop, addr);				\
 | |
| +-		if (addr == aend)					\
 | |
| +-			break;						\
 | |
| +-		addr += lsize;						\
 | |
| + 	}								\
 | |
| + }
 | |
| + 
 | |
| diff --git a/target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch b/target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch
 | |
| new file mode 100644
 | |
| index 0000000000..6c0828fa8a
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/301-mips_image_cmdline_hack.patch
 | |
| @@ -0,0 +1,38 @@
 | |
| +From: John Crispin <john@phrozen.org>
 | |
| +Subject: hack: kernel: add generic image_cmdline hack to MIPS targets
 | |
| +
 | |
| +lede-commit: d59f5b3a987a48508257a0ddbaeadc7909f9f976
 | |
| +Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 | |
| +---
 | |
| + arch/mips/Kconfig       | 4 ++++
 | |
| + arch/mips/kernel/head.S | 6 ++++++
 | |
| + 2 files changed, 10 insertions(+)
 | |
| +
 | |
| +--- a/arch/mips/Kconfig
 | |
| ++++ b/arch/mips/Kconfig
 | |
| +@@ -1162,6 +1162,10 @@ config MIPS_MSC
 | |
| + config SYNC_R4K
 | |
| + 	bool
 | |
| + 
 | |
| ++config IMAGE_CMDLINE_HACK
 | |
| ++	bool "OpenWrt specific image command line hack"
 | |
| ++	default n
 | |
| ++
 | |
| + config NO_IOPORT_MAP
 | |
| + 	def_bool n
 | |
| + 
 | |
| +--- a/arch/mips/kernel/head.S
 | |
| ++++ b/arch/mips/kernel/head.S
 | |
| +@@ -79,6 +79,12 @@ FEXPORT(__kernel_entry)
 | |
| + 	j	kernel_entry
 | |
| + #endif /* CONFIG_BOOT_RAW */
 | |
| + 
 | |
| ++#ifdef CONFIG_IMAGE_CMDLINE_HACK
 | |
| ++	.ascii	"CMDLINE:"
 | |
| ++EXPORT(__image_cmdline)
 | |
| ++	.fill	0x400
 | |
| ++#endif /* CONFIG_IMAGE_CMDLINE_HACK */
 | |
| ++
 | |
| + 	__REF
 | |
| + 
 | |
| + NESTED(kernel_entry, 16, sp)			# kernel entry point
 | |
| diff --git a/target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch b/target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4bb438295d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/321-powerpc_crtsavres_prereq.patch
 | |
| @@ -0,0 +1,38 @@
 | |
| +From 107c0964cb8db7ca28ac5199426414fdab3c274d Mon Sep 17 00:00:00 2001
 | |
| +From: "Alexandros C. Couloumbis" <alex@ozo.com>
 | |
| +Date: Fri, 7 Jul 2017 17:14:51 +0200
 | |
| +Subject: hack: arch: powerpc: drop register save/restore library from modules
 | |
| +
 | |
| +Upstream GCC uses a libgcc function for saving/restoring registers. This
 | |
| +makes the code bigger, and upstream kernels need to carry that function
 | |
| +for every single kernel module. Our GCC is patched to avoid those
 | |
| +references, so we can drop the extra bloat for modules.
 | |
| +
 | |
| +lede-commit: e8e1084654f50904e6bf77b70b2de3f137d7b3ec
 | |
| +Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
 | |
| +---
 | |
| + arch/powerpc/Makefile | 1 -
 | |
| + 1 file changed, 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/powerpc/Makefile
 | |
| ++++ b/arch/powerpc/Makefile
 | |
| +@@ -61,19 +61,6 @@ machine-$(CONFIG_PPC64) += 64
 | |
| + machine-$(CONFIG_CPU_LITTLE_ENDIAN) += le
 | |
| + UTS_MACHINE := $(subst $(space),,$(machine-y))
 | |
| + 
 | |
| +-# XXX This needs to be before we override LD below
 | |
| +-ifdef CONFIG_PPC32
 | |
| +-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
 | |
| +-else
 | |
| +-ifeq ($(call ld-ifversion, -ge, 225000000, y),y)
 | |
| +-# Have the linker provide sfpr if possible.
 | |
| +-# There is a corresponding test in arch/powerpc/lib/Makefile
 | |
| +-KBUILD_LDFLAGS_MODULE += --save-restore-funcs
 | |
| +-else
 | |
| +-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
 | |
| +-endif
 | |
| +-endif
 | |
| +-
 | |
| + ifdef CONFIG_CPU_LITTLE_ENDIAN
 | |
| + KBUILD_CFLAGS	+= -mlittle-endian
 | |
| + KBUILD_LDFLAGS	+= -EL
 | |
| diff --git a/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch b/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a414be6e84
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/400-block-fit-partition-parser.patch
 | |
| @@ -0,0 +1,177 @@
 | |
| +--- a/block/blk.h
 | |
| ++++ b/block/blk.h
 | |
| +@@ -357,6 +357,7 @@ char *disk_name(struct gendisk *hd, int
 | |
| + #define ADDPART_FLAG_NONE	0
 | |
| + #define ADDPART_FLAG_RAID	1
 | |
| + #define ADDPART_FLAG_WHOLEDISK	2
 | |
| ++#define ADDPART_FLAG_ROOTDEV	4
 | |
| + void delete_partition(struct hd_struct *part);
 | |
| + int bdev_add_partition(struct block_device *bdev, int partno,
 | |
| + 		sector_t start, sector_t length);
 | |
| +--- a/block/partitions/Kconfig
 | |
| ++++ b/block/partitions/Kconfig
 | |
| +@@ -101,6 +101,13 @@ config ATARI_PARTITION
 | |
| + 	  Say Y here if you would like to use hard disks under Linux which
 | |
| + 	  were partitioned under the Atari OS.
 | |
| + 
 | |
| ++config FIT_PARTITION
 | |
| ++	bool "Flattened-Image-Tree (FIT) partition support" if PARTITION_ADVANCED
 | |
| ++	default n
 | |
| ++	help
 | |
| ++	  Say Y here if your system needs to mount the filesystem part of
 | |
| ++	  a Flattened-Image-Tree (FIT) image commonly used with Das U-Boot.
 | |
| ++
 | |
| + config IBM_PARTITION
 | |
| + 	bool "IBM disk label and partition support"
 | |
| + 	depends on PARTITION_ADVANCED && S390
 | |
| +--- a/block/partitions/Makefile
 | |
| ++++ b/block/partitions/Makefile
 | |
| +@@ -8,6 +8,7 @@ obj-$(CONFIG_ACORN_PARTITION) += acorn.o
 | |
| + obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
 | |
| + obj-$(CONFIG_ATARI_PARTITION) += atari.o
 | |
| + obj-$(CONFIG_AIX_PARTITION) += aix.o
 | |
| ++obj-$(CONFIG_FIT_PARTITION) += fit.o
 | |
| + obj-$(CONFIG_CMDLINE_PARTITION) += cmdline.o
 | |
| + obj-$(CONFIG_MAC_PARTITION) += mac.o
 | |
| + obj-$(CONFIG_LDM_PARTITION) += ldm.o
 | |
| +--- a/block/partitions/check.h
 | |
| ++++ b/block/partitions/check.h
 | |
| +@@ -58,6 +58,7 @@ int amiga_partition(struct parsed_partit
 | |
| + int atari_partition(struct parsed_partitions *state);
 | |
| + int cmdline_partition(struct parsed_partitions *state);
 | |
| + int efi_partition(struct parsed_partitions *state);
 | |
| ++int fit_partition(struct parsed_partitions *state);
 | |
| + int ibm_partition(struct parsed_partitions *);
 | |
| + int karma_partition(struct parsed_partitions *state);
 | |
| + int ldm_partition(struct parsed_partitions *state);
 | |
| +@@ -68,3 +69,5 @@ int sgi_partition(struct parsed_partitio
 | |
| + int sun_partition(struct parsed_partitions *state);
 | |
| + int sysv68_partition(struct parsed_partitions *state);
 | |
| + int ultrix_partition(struct parsed_partitions *state);
 | |
| ++
 | |
| ++int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
 | |
| +--- a/block/partitions/core.c
 | |
| ++++ b/block/partitions/core.c
 | |
| +@@ -10,6 +10,10 @@
 | |
| + #include <linux/vmalloc.h>
 | |
| + #include <linux/blktrace_api.h>
 | |
| + #include <linux/raid/detect.h>
 | |
| ++#ifdef CONFIG_FIT_PARTITION
 | |
| ++#include <linux/root_dev.h>
 | |
| ++#endif
 | |
| ++
 | |
| + #include "check.h"
 | |
| + 
 | |
| + static int (*check_part[])(struct parsed_partitions *) = {
 | |
| +@@ -46,6 +50,9 @@ static int (*check_part[])(struct parsed
 | |
| + #ifdef CONFIG_EFI_PARTITION
 | |
| + 	efi_partition,		/* this must come before msdos */
 | |
| + #endif
 | |
| ++#ifdef CONFIG_FIT_PARTITION
 | |
| ++	fit_partition,
 | |
| ++#endif
 | |
| + #ifdef CONFIG_SGI_PARTITION
 | |
| + 	sgi_partition,
 | |
| + #endif
 | |
| +@@ -215,6 +222,18 @@ static ssize_t part_discard_alignment_sh
 | |
| + 				p->start_sect));
 | |
| + }
 | |
| + 
 | |
| ++static ssize_t part_name_show(struct device *dev,
 | |
| ++			      struct device_attribute *attr, char *buf)
 | |
| ++{
 | |
| ++	struct hd_struct *p = dev_to_part(dev);
 | |
| ++
 | |
| ++	if (p->info && p->info->volname)
 | |
| ++		return sprintf(buf, "%s\n", p->info->volname);
 | |
| ++
 | |
| ++	buf[0] = '\0';
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static DEVICE_ATTR(partition, 0444, part_partition_show, NULL);
 | |
| + static DEVICE_ATTR(start, 0444, part_start_show, NULL);
 | |
| + static DEVICE_ATTR(size, 0444, part_size_show, NULL);
 | |
| +@@ -223,6 +242,7 @@ static DEVICE_ATTR(alignment_offset, 044
 | |
| + static DEVICE_ATTR(discard_alignment, 0444, part_discard_alignment_show, NULL);
 | |
| + static DEVICE_ATTR(stat, 0444, part_stat_show, NULL);
 | |
| + static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL);
 | |
| ++static DEVICE_ATTR(name, 0444, part_name_show, NULL);
 | |
| + #ifdef CONFIG_FAIL_MAKE_REQUEST
 | |
| + static struct device_attribute dev_attr_fail =
 | |
| + 	__ATTR(make-it-fail, 0644, part_fail_show, part_fail_store);
 | |
| +@@ -237,6 +257,7 @@ static struct attribute *part_attrs[] =
 | |
| + 	&dev_attr_discard_alignment.attr,
 | |
| + 	&dev_attr_stat.attr,
 | |
| + 	&dev_attr_inflight.attr,
 | |
| ++	&dev_attr_name.attr,
 | |
| + #ifdef CONFIG_FAIL_MAKE_REQUEST
 | |
| + 	&dev_attr_fail.attr,
 | |
| + #endif
 | |
| +@@ -694,6 +715,11 @@ static bool blk_add_partition(struct gen
 | |
| + 	    (state->parts[p].flags & ADDPART_FLAG_RAID))
 | |
| + 		md_autodetect_dev(part_to_dev(part)->devt);
 | |
| + 
 | |
| ++#ifdef CONFIG_FIT_PARTITION
 | |
| ++	if ((state->parts[p].flags & ADDPART_FLAG_ROOTDEV) && ROOT_DEV == 0)
 | |
| ++		ROOT_DEV = part_to_dev(part)->devt;
 | |
| ++#endif
 | |
| ++
 | |
| + 	return true;
 | |
| + }
 | |
| + 
 | |
| +--- a/drivers/mtd/ubi/block.c
 | |
| ++++ b/drivers/mtd/ubi/block.c
 | |
| +@@ -396,7 +396,7 @@ int ubiblock_create(struct ubi_volume_in
 | |
| + 	dev->leb_size = vi->usable_leb_size;
 | |
| + 
 | |
| + 	/* Initialize the gendisk of this ubiblock device */
 | |
| +-	gd = alloc_disk(1);
 | |
| ++	gd = alloc_disk(0);
 | |
| + 	if (!gd) {
 | |
| + 		pr_err("UBI: block: alloc_disk failed\n");
 | |
| + 		ret = -ENODEV;
 | |
| +@@ -413,6 +413,7 @@ int ubiblock_create(struct ubi_volume_in
 | |
| + 		goto out_put_disk;
 | |
| + 	}
 | |
| + 	gd->private_data = dev;
 | |
| ++	gd->flags |= GENHD_FL_EXT_DEVT;
 | |
| + 	sprintf(gd->disk_name, "ubiblock%d_%d", dev->ubi_num, dev->vol_id);
 | |
| + 	set_capacity(gd, disk_capacity);
 | |
| + 	dev->gd = gd;
 | |
| +--- a/block/partitions/efi.c
 | |
| ++++ b/block/partitions/efi.c
 | |
| +@@ -706,6 +706,9 @@ int efi_partition(struct parsed_partitio
 | |
| + 	gpt_entry *ptes = NULL;
 | |
| + 	u32 i;
 | |
| + 	unsigned ssz = bdev_logical_block_size(state->bdev) / 512;
 | |
| ++#ifdef CONFIG_FIT_PARTITION
 | |
| ++	u32 extra_slot = 64;
 | |
| ++#endif
 | |
| + 
 | |
| + 	if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
 | |
| + 		kfree(gpt);
 | |
| +@@ -739,6 +742,11 @@ int efi_partition(struct parsed_partitio
 | |
| + 				ARRAY_SIZE(ptes[i].partition_name));
 | |
| + 		utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
 | |
| + 		state->parts[i + 1].has_info = true;
 | |
| ++#ifdef CONFIG_FIT_PARTITION
 | |
| ++		/* If this is a U-Boot FIT volume it may have subpartitions */
 | |
| ++		if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
 | |
| ++			(void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
 | |
| ++#endif
 | |
| + 	}
 | |
| + 	kfree(ptes);
 | |
| + 	kfree(gpt);
 | |
| +--- a/block/partitions/efi.h
 | |
| ++++ b/block/partitions/efi.h
 | |
| +@@ -52,6 +52,9 @@
 | |
| + #define PARTITION_LINUX_LVM_GUID \
 | |
| +     EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
 | |
| +               0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
 | |
| ++#define PARTITION_LINUX_FIT_GUID \
 | |
| ++    EFI_GUID( 0xcae9be83, 0xb15f, 0x49cc, \
 | |
| ++              0x86, 0x3f, 0x08, 0x1b, 0x74, 0x4a, 0x2d, 0x93)
 | |
| + 
 | |
| + typedef struct _gpt_header {
 | |
| + 	__le64 signature;
 | |
| diff --git a/target/linux/generic/hack-5.10/531-debloat_lzma.patch b/target/linux/generic/hack-5.10/531-debloat_lzma.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2f70eee3e9
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/531-debloat_lzma.patch
 | |
| @@ -0,0 +1,1040 @@
 | |
| +From 3fd297761ac246c54d7723c57fca95c112b99465 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sat, 15 Jul 2017 21:15:44 +0200
 | |
| +Subject: lzma: de-bloat the lzma library used by jffs2
 | |
| +
 | |
| +lede-commit: 3fd1dd08fbcbb78b34efefd32c3032e5c99108d6
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/linux/lzma/LzFind.h  |  17 ---
 | |
| + include/linux/lzma/LzmaDec.h | 101 ---------------
 | |
| + include/linux/lzma/LzmaEnc.h |  20 ---
 | |
| + lib/lzma/LzFind.c            | 287 ++++---------------------------------------
 | |
| + lib/lzma/LzmaDec.c           |  86 +------------
 | |
| + lib/lzma/LzmaEnc.c           | 172 ++------------------------
 | |
| + 6 files changed, 42 insertions(+), 641 deletions(-)
 | |
| +
 | |
| +--- a/include/linux/lzma/LzFind.h
 | |
| ++++ b/include/linux/lzma/LzFind.h
 | |
| +@@ -55,11 +55,6 @@ typedef struct _CMatchFinder
 | |
| + 
 | |
| + #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
 | |
| + 
 | |
| +-int MatchFinder_NeedMove(CMatchFinder *p);
 | |
| +-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
 | |
| +-void MatchFinder_MoveBlock(CMatchFinder *p);
 | |
| +-void MatchFinder_ReadIfRequired(CMatchFinder *p);
 | |
| +-
 | |
| + void MatchFinder_Construct(CMatchFinder *p);
 | |
| + 
 | |
| + /* Conditions:
 | |
| +@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p,
 | |
| +     UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
 | |
| +     ISzAlloc *alloc);
 | |
| + void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
 | |
| +-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
 | |
| +-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
 | |
| +-
 | |
| +-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
 | |
| +-    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
 | |
| +-    UInt32 *distances, UInt32 maxLen);
 | |
| + 
 | |
| + /*
 | |
| + Conditions:
 | |
| +@@ -102,12 +91,6 @@ typedef struct _IMatchFinder
 | |
| + 
 | |
| + void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
 | |
| + 
 | |
| +-void MatchFinder_Init(CMatchFinder *p);
 | |
| +-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
 | |
| +-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
 | |
| +-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
 | |
| +-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
 | |
| +-
 | |
| + #ifdef __cplusplus
 | |
| + }
 | |
| + #endif
 | |
| +--- a/include/linux/lzma/LzmaDec.h
 | |
| ++++ b/include/linux/lzma/LzmaDec.h
 | |
| +@@ -31,14 +31,6 @@ typedef struct _CLzmaProps
 | |
| +   UInt32 dicSize;
 | |
| + } CLzmaProps;
 | |
| + 
 | |
| +-/* LzmaProps_Decode - decodes properties
 | |
| +-Returns:
 | |
| +-  SZ_OK
 | |
| +-  SZ_ERROR_UNSUPPORTED - Unsupported properties
 | |
| +-*/
 | |
| +-
 | |
| +-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
 | |
| +-
 | |
| + 
 | |
| + /* ---------- LZMA Decoder state ---------- */
 | |
| + 
 | |
| +@@ -70,8 +62,6 @@ typedef struct
 | |
| + 
 | |
| + #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
 | |
| + 
 | |
| +-void LzmaDec_Init(CLzmaDec *p);
 | |
| +-
 | |
| + /* There are two types of LZMA streams:
 | |
| +      0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
 | |
| +      1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
 | |
| +@@ -108,97 +98,6 @@ typedef enum
 | |
| + 
 | |
| + /* ELzmaStatus is used only as output value for function call */
 | |
| + 
 | |
| +-
 | |
| +-/* ---------- Interfaces ---------- */
 | |
| +-
 | |
| +-/* There are 3 levels of interfaces:
 | |
| +-     1) Dictionary Interface
 | |
| +-     2) Buffer Interface
 | |
| +-     3) One Call Interface
 | |
| +-   You can select any of these interfaces, but don't mix functions from different
 | |
| +-   groups for same object. */
 | |
| +-
 | |
| +-
 | |
| +-/* There are two variants to allocate state for Dictionary Interface:
 | |
| +-     1) LzmaDec_Allocate / LzmaDec_Free
 | |
| +-     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
 | |
| +-   You can use variant 2, if you set dictionary buffer manually.
 | |
| +-   For Buffer Interface you must always use variant 1.
 | |
| +-
 | |
| +-LzmaDec_Allocate* can return:
 | |
| +-  SZ_OK
 | |
| +-  SZ_ERROR_MEM         - Memory allocation error
 | |
| +-  SZ_ERROR_UNSUPPORTED - Unsupported properties
 | |
| +-*/
 | |
| +-
 | |
| +-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
 | |
| +-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
 | |
| +-
 | |
| +-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
 | |
| +-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
 | |
| +-
 | |
| +-/* ---------- Dictionary Interface ---------- */
 | |
| +-
 | |
| +-/* You can use it, if you want to eliminate the overhead for data copying from
 | |
| +-   dictionary to some other external buffer.
 | |
| +-   You must work with CLzmaDec variables directly in this interface.
 | |
| +-
 | |
| +-   STEPS:
 | |
| +-     LzmaDec_Constr()
 | |
| +-     LzmaDec_Allocate()
 | |
| +-     for (each new stream)
 | |
| +-     {
 | |
| +-       LzmaDec_Init()
 | |
| +-       while (it needs more decompression)
 | |
| +-       {
 | |
| +-         LzmaDec_DecodeToDic()
 | |
| +-         use data from CLzmaDec::dic and update CLzmaDec::dicPos
 | |
| +-       }
 | |
| +-     }
 | |
| +-     LzmaDec_Free()
 | |
| +-*/
 | |
| +-
 | |
| +-/* LzmaDec_DecodeToDic
 | |
| +-
 | |
| +-   The decoding to internal dictionary buffer (CLzmaDec::dic).
 | |
| +-   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
 | |
| +-
 | |
| +-finishMode:
 | |
| +-  It has meaning only if the decoding reaches output limit (dicLimit).
 | |
| +-  LZMA_FINISH_ANY - Decode just dicLimit bytes.
 | |
| +-  LZMA_FINISH_END - Stream must be finished after dicLimit.
 | |
| +-
 | |
| +-Returns:
 | |
| +-  SZ_OK
 | |
| +-    status:
 | |
| +-      LZMA_STATUS_FINISHED_WITH_MARK
 | |
| +-      LZMA_STATUS_NOT_FINISHED
 | |
| +-      LZMA_STATUS_NEEDS_MORE_INPUT
 | |
| +-      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
 | |
| +-  SZ_ERROR_DATA - Data error
 | |
| +-*/
 | |
| +-
 | |
| +-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
 | |
| +-    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
 | |
| +-
 | |
| +-
 | |
| +-/* ---------- Buffer Interface ---------- */
 | |
| +-
 | |
| +-/* It's zlib-like interface.
 | |
| +-   See LzmaDec_DecodeToDic description for information about STEPS and return results,
 | |
| +-   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
 | |
| +-   to work with CLzmaDec variables manually.
 | |
| +-
 | |
| +-finishMode:
 | |
| +-  It has meaning only if the decoding reaches output limit (*destLen).
 | |
| +-  LZMA_FINISH_ANY - Decode just destLen bytes.
 | |
| +-  LZMA_FINISH_END - Stream must be finished after (*destLen).
 | |
| +-*/
 | |
| +-
 | |
| +-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
 | |
| +-    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
 | |
| +-
 | |
| +-
 | |
| + /* ---------- One Call Interface ---------- */
 | |
| + 
 | |
| + /* LzmaDecode
 | |
| +--- a/include/linux/lzma/LzmaEnc.h
 | |
| ++++ b/include/linux/lzma/LzmaEnc.h
 | |
| +@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps
 | |
| + } CLzmaEncProps;
 | |
| + 
 | |
| + void LzmaEncProps_Init(CLzmaEncProps *p);
 | |
| +-void LzmaEncProps_Normalize(CLzmaEncProps *p);
 | |
| +-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
 | |
| +-
 | |
| + 
 | |
| + /* ---------- CLzmaEncHandle Interface ---------- */
 | |
| + 
 | |
| +@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
 | |
| + void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| + SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
 | |
| + SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
 | |
| +-SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
 | |
| +-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| + SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
 | |
| +     int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| + 
 | |
| +-/* ---------- One Call Interface ---------- */
 | |
| +-
 | |
| +-/* LzmaEncode
 | |
| +-Return code:
 | |
| +-  SZ_OK               - OK
 | |
| +-  SZ_ERROR_MEM        - Memory allocation error
 | |
| +-  SZ_ERROR_PARAM      - Incorrect paramater
 | |
| +-  SZ_ERROR_OUTPUT_EOF - output buffer overflow
 | |
| +-  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
 | |
| +-*/
 | |
| +-
 | |
| +-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
 | |
| +-    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
 | |
| +-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| +-
 | |
| + #ifdef __cplusplus
 | |
| + }
 | |
| + #endif
 | |
| +--- a/lib/lzma/LzFind.c
 | |
| ++++ b/lib/lzma/LzFind.c
 | |
| +@@ -14,9 +14,15 @@
 | |
| + 
 | |
| + #define kStartMaxLen 3
 | |
| + 
 | |
| ++#if 0
 | |
| ++#define DIRECT_INPUT	p->directInput
 | |
| ++#else
 | |
| ++#define DIRECT_INPUT	1
 | |
| ++#endif
 | |
| ++
 | |
| + static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
 | |
| + {
 | |
| +-  if (!p->directInput)
 | |
| ++  if (!DIRECT_INPUT)
 | |
| +   {
 | |
| +     alloc->Free(alloc, p->bufferBase);
 | |
| +     p->bufferBase = 0;
 | |
| +@@ -28,7 +34,7 @@ static void LzInWindow_Free(CMatchFinder
 | |
| + static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
 | |
| + {
 | |
| +   UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
 | |
| +-  if (p->directInput)
 | |
| ++  if (DIRECT_INPUT)
 | |
| +   {
 | |
| +     p->blockSize = blockSize;
 | |
| +     return 1;
 | |
| +@@ -42,12 +48,12 @@ static int LzInWindow_Create(CMatchFinde
 | |
| +   return (p->bufferBase != 0);
 | |
| + }
 | |
| + 
 | |
| +-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
 | |
| +-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
 | |
| ++static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
 | |
| ++static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
 | |
| + 
 | |
| +-UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
 | |
| ++static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
 | |
| + 
 | |
| +-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
 | |
| ++static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
 | |
| + {
 | |
| +   p->posLimit -= subValue;
 | |
| +   p->pos -= subValue;
 | |
| +@@ -58,7 +64,7 @@ static void MatchFinder_ReadBlock(CMatch
 | |
| + {
 | |
| +   if (p->streamEndWasReached || p->result != SZ_OK)
 | |
| +     return;
 | |
| +-  if (p->directInput)
 | |
| ++  if (DIRECT_INPUT)
 | |
| +   {
 | |
| +     UInt32 curSize = 0xFFFFFFFF - p->streamPos;
 | |
| +     if (curSize > p->directInputRem)
 | |
| +@@ -89,7 +95,7 @@ static void MatchFinder_ReadBlock(CMatch
 | |
| +   }
 | |
| + }
 | |
| + 
 | |
| +-void MatchFinder_MoveBlock(CMatchFinder *p)
 | |
| ++static void MatchFinder_MoveBlock(CMatchFinder *p)
 | |
| + {
 | |
| +   memmove(p->bufferBase,
 | |
| +     p->buffer - p->keepSizeBefore,
 | |
| +@@ -97,22 +103,14 @@ void MatchFinder_MoveBlock(CMatchFinder
 | |
| +   p->buffer = p->bufferBase + p->keepSizeBefore;
 | |
| + }
 | |
| + 
 | |
| +-int MatchFinder_NeedMove(CMatchFinder *p)
 | |
| ++static int MatchFinder_NeedMove(CMatchFinder *p)
 | |
| + {
 | |
| +-  if (p->directInput)
 | |
| ++  if (DIRECT_INPUT)
 | |
| +     return 0;
 | |
| +   /* if (p->streamEndWasReached) return 0; */
 | |
| +   return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
 | |
| + }
 | |
| + 
 | |
| +-void MatchFinder_ReadIfRequired(CMatchFinder *p)
 | |
| +-{
 | |
| +-  if (p->streamEndWasReached)
 | |
| +-    return;
 | |
| +-  if (p->keepSizeAfter >= p->streamPos - p->pos)
 | |
| +-    MatchFinder_ReadBlock(p);
 | |
| +-}
 | |
| +-
 | |
| + static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
 | |
| + {
 | |
| +   if (MatchFinder_NeedMove(p))
 | |
| +@@ -268,7 +266,7 @@ static void MatchFinder_SetLimits(CMatch
 | |
| +   p->posLimit = p->pos + limit;
 | |
| + }
 | |
| + 
 | |
| +-void MatchFinder_Init(CMatchFinder *p)
 | |
| ++static void MatchFinder_Init(CMatchFinder *p)
 | |
| + {
 | |
| +   UInt32 i;
 | |
| +   for (i = 0; i < p->hashSizeSum; i++)
 | |
| +@@ -287,7 +285,7 @@ static UInt32 MatchFinder_GetSubValue(CM
 | |
| +   return (p->pos - p->historySize - 1) & kNormalizeMask;
 | |
| + }
 | |
| + 
 | |
| +-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
 | |
| ++static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
 | |
| + {
 | |
| +   UInt32 i;
 | |
| +   for (i = 0; i < numItems; i++)
 | |
| +@@ -319,38 +317,7 @@ static void MatchFinder_CheckLimits(CMat
 | |
| +   MatchFinder_SetLimits(p);
 | |
| + }
 | |
| + 
 | |
| +-static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
 | |
| +-    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
 | |
| +-    UInt32 *distances, UInt32 maxLen)
 | |
| +-{
 | |
| +-  son[_cyclicBufferPos] = curMatch;
 | |
| +-  for (;;)
 | |
| +-  {
 | |
| +-    UInt32 delta = pos - curMatch;
 | |
| +-    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
 | |
| +-      return distances;
 | |
| +-    {
 | |
| +-      const Byte *pb = cur - delta;
 | |
| +-      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
 | |
| +-      if (pb[maxLen] == cur[maxLen] && *pb == *cur)
 | |
| +-      {
 | |
| +-        UInt32 len = 0;
 | |
| +-        while (++len != lenLimit)
 | |
| +-          if (pb[len] != cur[len])
 | |
| +-            break;
 | |
| +-        if (maxLen < len)
 | |
| +-        {
 | |
| +-          *distances++ = maxLen = len;
 | |
| +-          *distances++ = delta - 1;
 | |
| +-          if (len == lenLimit)
 | |
| +-            return distances;
 | |
| +-        }
 | |
| +-      }
 | |
| +-    }
 | |
| +-  }
 | |
| +-}
 | |
| +-
 | |
| +-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
 | |
| ++static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
 | |
| +     UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
 | |
| +     UInt32 *distances, UInt32 maxLen)
 | |
| + {
 | |
| +@@ -460,10 +427,10 @@ static void SkipMatchesSpec(UInt32 lenLi
 | |
| +   p->buffer++; \
 | |
| +   if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
 | |
| + 
 | |
| +-#define MOVE_POS_RET MOVE_POS return offset;
 | |
| +-
 | |
| + static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
 | |
| + 
 | |
| ++#define MOVE_POS_RET MatchFinder_MovePos(p); return offset;
 | |
| ++
 | |
| + #define GET_MATCHES_HEADER2(minLen, ret_op) \
 | |
| +   UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
 | |
| +   lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
 | |
| +@@ -479,62 +446,7 @@ static void MatchFinder_MovePos(CMatchFi
 | |
| +   distances + offset, maxLen) - distances); MOVE_POS_RET;
 | |
| + 
 | |
| + #define SKIP_FOOTER \
 | |
| +-  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
 | |
| +-
 | |
| +-static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| +-{
 | |
| +-  UInt32 offset;
 | |
| +-  GET_MATCHES_HEADER(2)
 | |
| +-  HASH2_CALC;
 | |
| +-  curMatch = p->hash[hashValue];
 | |
| +-  p->hash[hashValue] = p->pos;
 | |
| +-  offset = 0;
 | |
| +-  GET_MATCHES_FOOTER(offset, 1)
 | |
| +-}
 | |
| +-
 | |
| +-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| +-{
 | |
| +-  UInt32 offset;
 | |
| +-  GET_MATCHES_HEADER(3)
 | |
| +-  HASH_ZIP_CALC;
 | |
| +-  curMatch = p->hash[hashValue];
 | |
| +-  p->hash[hashValue] = p->pos;
 | |
| +-  offset = 0;
 | |
| +-  GET_MATCHES_FOOTER(offset, 2)
 | |
| +-}
 | |
| +-
 | |
| +-static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| +-{
 | |
| +-  UInt32 hash2Value, delta2, maxLen, offset;
 | |
| +-  GET_MATCHES_HEADER(3)
 | |
| +-
 | |
| +-  HASH3_CALC;
 | |
| +-
 | |
| +-  delta2 = p->pos - p->hash[hash2Value];
 | |
| +-  curMatch = p->hash[kFix3HashSize + hashValue];
 | |
| +-
 | |
| +-  p->hash[hash2Value] =
 | |
| +-  p->hash[kFix3HashSize + hashValue] = p->pos;
 | |
| +-
 | |
| +-
 | |
| +-  maxLen = 2;
 | |
| +-  offset = 0;
 | |
| +-  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
 | |
| +-  {
 | |
| +-    for (; maxLen != lenLimit; maxLen++)
 | |
| +-      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
 | |
| +-        break;
 | |
| +-    distances[0] = maxLen;
 | |
| +-    distances[1] = delta2 - 1;
 | |
| +-    offset = 2;
 | |
| +-    if (maxLen == lenLimit)
 | |
| +-    {
 | |
| +-      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
 | |
| +-      MOVE_POS_RET;
 | |
| +-    }
 | |
| +-  }
 | |
| +-  GET_MATCHES_FOOTER(offset, maxLen)
 | |
| +-}
 | |
| ++  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MatchFinder_MovePos(p);
 | |
| + 
 | |
| + static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| + {
 | |
| +@@ -583,108 +495,6 @@ static UInt32 Bt4_MatchFinder_GetMatches
 | |
| +   GET_MATCHES_FOOTER(offset, maxLen)
 | |
| + }
 | |
| + 
 | |
| +-static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| +-{
 | |
| +-  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
 | |
| +-  GET_MATCHES_HEADER(4)
 | |
| +-
 | |
| +-  HASH4_CALC;
 | |
| +-
 | |
| +-  delta2 = p->pos - p->hash[                hash2Value];
 | |
| +-  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
 | |
| +-  curMatch = p->hash[kFix4HashSize + hashValue];
 | |
| +-
 | |
| +-  p->hash[                hash2Value] =
 | |
| +-  p->hash[kFix3HashSize + hash3Value] =
 | |
| +-  p->hash[kFix4HashSize + hashValue] = p->pos;
 | |
| +-
 | |
| +-  maxLen = 1;
 | |
| +-  offset = 0;
 | |
| +-  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
 | |
| +-  {
 | |
| +-    distances[0] = maxLen = 2;
 | |
| +-    distances[1] = delta2 - 1;
 | |
| +-    offset = 2;
 | |
| +-  }
 | |
| +-  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
 | |
| +-  {
 | |
| +-    maxLen = 3;
 | |
| +-    distances[offset + 1] = delta3 - 1;
 | |
| +-    offset += 2;
 | |
| +-    delta2 = delta3;
 | |
| +-  }
 | |
| +-  if (offset != 0)
 | |
| +-  {
 | |
| +-    for (; maxLen != lenLimit; maxLen++)
 | |
| +-      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
 | |
| +-        break;
 | |
| +-    distances[offset - 2] = maxLen;
 | |
| +-    if (maxLen == lenLimit)
 | |
| +-    {
 | |
| +-      p->son[p->cyclicBufferPos] = curMatch;
 | |
| +-      MOVE_POS_RET;
 | |
| +-    }
 | |
| +-  }
 | |
| +-  if (maxLen < 3)
 | |
| +-    maxLen = 3;
 | |
| +-  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
 | |
| +-    distances + offset, maxLen) - (distances));
 | |
| +-  MOVE_POS_RET
 | |
| +-}
 | |
| +-
 | |
| +-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| +-{
 | |
| +-  UInt32 offset;
 | |
| +-  GET_MATCHES_HEADER(3)
 | |
| +-  HASH_ZIP_CALC;
 | |
| +-  curMatch = p->hash[hashValue];
 | |
| +-  p->hash[hashValue] = p->pos;
 | |
| +-  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
 | |
| +-    distances, 2) - (distances));
 | |
| +-  MOVE_POS_RET
 | |
| +-}
 | |
| +-
 | |
| +-static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| +-{
 | |
| +-  do
 | |
| +-  {
 | |
| +-    SKIP_HEADER(2)
 | |
| +-    HASH2_CALC;
 | |
| +-    curMatch = p->hash[hashValue];
 | |
| +-    p->hash[hashValue] = p->pos;
 | |
| +-    SKIP_FOOTER
 | |
| +-  }
 | |
| +-  while (--num != 0);
 | |
| +-}
 | |
| +-
 | |
| +-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| +-{
 | |
| +-  do
 | |
| +-  {
 | |
| +-    SKIP_HEADER(3)
 | |
| +-    HASH_ZIP_CALC;
 | |
| +-    curMatch = p->hash[hashValue];
 | |
| +-    p->hash[hashValue] = p->pos;
 | |
| +-    SKIP_FOOTER
 | |
| +-  }
 | |
| +-  while (--num != 0);
 | |
| +-}
 | |
| +-
 | |
| +-static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| +-{
 | |
| +-  do
 | |
| +-  {
 | |
| +-    UInt32 hash2Value;
 | |
| +-    SKIP_HEADER(3)
 | |
| +-    HASH3_CALC;
 | |
| +-    curMatch = p->hash[kFix3HashSize + hashValue];
 | |
| +-    p->hash[hash2Value] =
 | |
| +-    p->hash[kFix3HashSize + hashValue] = p->pos;
 | |
| +-    SKIP_FOOTER
 | |
| +-  }
 | |
| +-  while (--num != 0);
 | |
| +-}
 | |
| +-
 | |
| + static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| + {
 | |
| +   do
 | |
| +@@ -701,61 +511,12 @@ static void Bt4_MatchFinder_Skip(CMatchF
 | |
| +   while (--num != 0);
 | |
| + }
 | |
| + 
 | |
| +-static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| +-{
 | |
| +-  do
 | |
| +-  {
 | |
| +-    UInt32 hash2Value, hash3Value;
 | |
| +-    SKIP_HEADER(4)
 | |
| +-    HASH4_CALC;
 | |
| +-    curMatch = p->hash[kFix4HashSize + hashValue];
 | |
| +-    p->hash[                hash2Value] =
 | |
| +-    p->hash[kFix3HashSize + hash3Value] =
 | |
| +-    p->hash[kFix4HashSize + hashValue] = p->pos;
 | |
| +-    p->son[p->cyclicBufferPos] = curMatch;
 | |
| +-    MOVE_POS
 | |
| +-  }
 | |
| +-  while (--num != 0);
 | |
| +-}
 | |
| +-
 | |
| +-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| +-{
 | |
| +-  do
 | |
| +-  {
 | |
| +-    SKIP_HEADER(3)
 | |
| +-    HASH_ZIP_CALC;
 | |
| +-    curMatch = p->hash[hashValue];
 | |
| +-    p->hash[hashValue] = p->pos;
 | |
| +-    p->son[p->cyclicBufferPos] = curMatch;
 | |
| +-    MOVE_POS
 | |
| +-  }
 | |
| +-  while (--num != 0);
 | |
| +-}
 | |
| +-
 | |
| + void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
 | |
| + {
 | |
| +   vTable->Init = (Mf_Init_Func)MatchFinder_Init;
 | |
| +   vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
 | |
| +   vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
 | |
| +   vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
 | |
| +-  if (!p->btMode)
 | |
| +-  {
 | |
| +-    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
 | |
| +-    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
 | |
| +-  }
 | |
| +-  else if (p->numHashBytes == 2)
 | |
| +-  {
 | |
| +-    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
 | |
| +-    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
 | |
| +-  }
 | |
| +-  else if (p->numHashBytes == 3)
 | |
| +-  {
 | |
| +-    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
 | |
| +-    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
 | |
| +-  }
 | |
| +-  else
 | |
| +-  {
 | |
| +-    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
 | |
| +-    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
 | |
| +-  }
 | |
| ++  vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
 | |
| ++  vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
 | |
| + }
 | |
| +--- a/lib/lzma/LzmaDec.c
 | |
| ++++ b/lib/lzma/LzmaDec.c
 | |
| +@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p,
 | |
| +   p->needFlush = 0;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
 | |
| ++static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
 | |
| + {
 | |
| +   p->needFlush = 1;
 | |
| +   p->remainLen = 0;
 | |
| +@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p
 | |
| +     p->needInitState = 1;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaDec_Init(CLzmaDec *p)
 | |
| ++static void LzmaDec_Init(CLzmaDec *p)
 | |
| + {
 | |
| +   p->dicPos = 0;
 | |
| +   LzmaDec_InitDicAndState(p, True, True);
 | |
| +@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD
 | |
| +   p->needInitState = 0;
 | |
| + }
 | |
| + 
 | |
| +-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
 | |
| ++static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
 | |
| +     ELzmaFinishMode finishMode, ELzmaStatus *status)
 | |
| + {
 | |
| +   SizeT inSize = *srcLen;
 | |
| +@@ -837,65 +837,13 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si
 | |
| +   return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
 | |
| + }
 | |
| + 
 | |
| +-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
 | |
| +-{
 | |
| +-  SizeT outSize = *destLen;
 | |
| +-  SizeT inSize = *srcLen;
 | |
| +-  *srcLen = *destLen = 0;
 | |
| +-  for (;;)
 | |
| +-  {
 | |
| +-    SizeT inSizeCur = inSize, outSizeCur, dicPos;
 | |
| +-    ELzmaFinishMode curFinishMode;
 | |
| +-    SRes res;
 | |
| +-    if (p->dicPos == p->dicBufSize)
 | |
| +-      p->dicPos = 0;
 | |
| +-    dicPos = p->dicPos;
 | |
| +-    if (outSize > p->dicBufSize - dicPos)
 | |
| +-    {
 | |
| +-      outSizeCur = p->dicBufSize;
 | |
| +-      curFinishMode = LZMA_FINISH_ANY;
 | |
| +-    }
 | |
| +-    else
 | |
| +-    {
 | |
| +-      outSizeCur = dicPos + outSize;
 | |
| +-      curFinishMode = finishMode;
 | |
| +-    }
 | |
| +-
 | |
| +-    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
 | |
| +-    src += inSizeCur;
 | |
| +-    inSize -= inSizeCur;
 | |
| +-    *srcLen += inSizeCur;
 | |
| +-    outSizeCur = p->dicPos - dicPos;
 | |
| +-    memcpy(dest, p->dic + dicPos, outSizeCur);
 | |
| +-    dest += outSizeCur;
 | |
| +-    outSize -= outSizeCur;
 | |
| +-    *destLen += outSizeCur;
 | |
| +-    if (res != 0)
 | |
| +-      return res;
 | |
| +-    if (outSizeCur == 0 || outSize == 0)
 | |
| +-      return SZ_OK;
 | |
| +-  }
 | |
| +-}
 | |
| +-
 | |
| +-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
 | |
| ++static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
 | |
| + {
 | |
| +   alloc->Free(alloc, p->probs);
 | |
| +   p->probs = 0;
 | |
| + }
 | |
| + 
 | |
| +-static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
 | |
| +-{
 | |
| +-  alloc->Free(alloc, p->dic);
 | |
| +-  p->dic = 0;
 | |
| +-}
 | |
| +-
 | |
| +-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
 | |
| +-{
 | |
| +-  LzmaDec_FreeProbs(p, alloc);
 | |
| +-  LzmaDec_FreeDict(p, alloc);
 | |
| +-}
 | |
| +-
 | |
| +-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
 | |
| ++static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
 | |
| + {
 | |
| +   UInt32 dicSize;
 | |
| +   Byte d;
 | |
| +@@ -935,7 +883,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma
 | |
| +   return SZ_OK;
 | |
| + }
 | |
| + 
 | |
| +-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
 | |
| ++static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
 | |
| + {
 | |
| +   CLzmaProps propNew;
 | |
| +   RINOK(LzmaProps_Decode(&propNew, props, propsSize));
 | |
| +@@ -943,28 +891,6 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p,
 | |
| +   p->prop = propNew;
 | |
| +   return SZ_OK;
 | |
| + }
 | |
| +-
 | |
| +-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
 | |
| +-{
 | |
| +-  CLzmaProps propNew;
 | |
| +-  SizeT dicBufSize;
 | |
| +-  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
 | |
| +-  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
 | |
| +-  dicBufSize = propNew.dicSize;
 | |
| +-  if (p->dic == 0 || dicBufSize != p->dicBufSize)
 | |
| +-  {
 | |
| +-    LzmaDec_FreeDict(p, alloc);
 | |
| +-    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
 | |
| +-    if (p->dic == 0)
 | |
| +-    {
 | |
| +-      LzmaDec_FreeProbs(p, alloc);
 | |
| +-      return SZ_ERROR_MEM;
 | |
| +-    }
 | |
| +-  }
 | |
| +-  p->dicBufSize = dicBufSize;
 | |
| +-  p->prop = propNew;
 | |
| +-  return SZ_OK;
 | |
| +-}
 | |
| + 
 | |
| + SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
 | |
| +     const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
 | |
| +--- a/lib/lzma/LzmaEnc.c
 | |
| ++++ b/lib/lzma/LzmaEnc.c
 | |
| +@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
 | |
| +   p->writeEndMark = 0;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEncProps_Normalize(CLzmaEncProps *p)
 | |
| ++static void LzmaEncProps_Normalize(CLzmaEncProps *p)
 | |
| + {
 | |
| +   int level = p->level;
 | |
| +   if (level < 0) level = 5;
 | |
| +@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp
 | |
| +       #endif
 | |
| + }
 | |
| + 
 | |
| +-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
 | |
| ++static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
 | |
| + {
 | |
| +   CLzmaEncProps props = *props2;
 | |
| +   LzmaEncProps_Normalize(&props);
 | |
| +@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL
 | |
| + 
 | |
| + #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
 | |
| + 
 | |
| +-UInt32 GetPosSlot1(UInt32 pos)
 | |
| ++static UInt32 GetPosSlot1(UInt32 pos)
 | |
| + {
 | |
| +   UInt32 res;
 | |
| +   BSR2_RET(pos, res);
 | |
| +@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos)
 | |
| + #define kNumLogBits (9 + (int)sizeof(size_t) / 2)
 | |
| + #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
 | |
| + 
 | |
| +-void LzmaEnc_FastPosInit(Byte *g_FastPos)
 | |
| ++static void LzmaEnc_FastPosInit(Byte *g_FastPos)
 | |
| + {
 | |
| +   int c = 2, slotFast;
 | |
| +   g_FastPos[0] = 0;
 | |
| +@@ -339,58 +339,6 @@ typedef struct
 | |
| +   CSaveState saveState;
 | |
| + } CLzmaEnc;
 | |
| + 
 | |
| +-void LzmaEnc_SaveState(CLzmaEncHandle pp)
 | |
| +-{
 | |
| +-  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +-  CSaveState *dest = &p->saveState;
 | |
| +-  int i;
 | |
| +-  dest->lenEnc = p->lenEnc;
 | |
| +-  dest->repLenEnc = p->repLenEnc;
 | |
| +-  dest->state = p->state;
 | |
| +-
 | |
| +-  for (i = 0; i < kNumStates; i++)
 | |
| +-  {
 | |
| +-    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
 | |
| +-    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
 | |
| +-  }
 | |
| +-  for (i = 0; i < kNumLenToPosStates; i++)
 | |
| +-    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
 | |
| +-  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
 | |
| +-  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
 | |
| +-  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
 | |
| +-  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
 | |
| +-  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
 | |
| +-  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
 | |
| +-  memcpy(dest->reps, p->reps, sizeof(p->reps));
 | |
| +-  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
 | |
| +-}
 | |
| +-
 | |
| +-void LzmaEnc_RestoreState(CLzmaEncHandle pp)
 | |
| +-{
 | |
| +-  CLzmaEnc *dest = (CLzmaEnc *)pp;
 | |
| +-  const CSaveState *p = &dest->saveState;
 | |
| +-  int i;
 | |
| +-  dest->lenEnc = p->lenEnc;
 | |
| +-  dest->repLenEnc = p->repLenEnc;
 | |
| +-  dest->state = p->state;
 | |
| +-
 | |
| +-  for (i = 0; i < kNumStates; i++)
 | |
| +-  {
 | |
| +-    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
 | |
| +-    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
 | |
| +-  }
 | |
| +-  for (i = 0; i < kNumLenToPosStates; i++)
 | |
| +-    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
 | |
| +-  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
 | |
| +-  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
 | |
| +-  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
 | |
| +-  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
 | |
| +-  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
 | |
| +-  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
 | |
| +-  memcpy(dest->reps, p->reps, sizeof(p->reps));
 | |
| +-  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
 | |
| +-}
 | |
| +-
 | |
| + SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
 | |
| + {
 | |
| +   CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +@@ -600,7 +548,7 @@ static void LitEnc_EncodeMatched(CRangeE
 | |
| +   while (symbol < 0x10000);
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
 | |
| ++static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
 | |
| + {
 | |
| +   UInt32 i;
 | |
| +   for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
 | |
| +@@ -1676,7 +1624,7 @@ static void FillDistancesPrices(CLzmaEnc
 | |
| +   p->matchPriceCount = 0;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEnc_Construct(CLzmaEnc *p)
 | |
| ++static void LzmaEnc_Construct(CLzmaEnc *p)
 | |
| + {
 | |
| +   RangeEnc_Construct(&p->rc);
 | |
| +   MatchFinder_Construct(&p->matchFinderBase);
 | |
| +@@ -1709,7 +1657,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
 | |
| +   return p;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
 | |
| ++static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
 | |
| + {
 | |
| +   alloc->Free(alloc, p->litProbs);
 | |
| +   alloc->Free(alloc, p->saveState.litProbs);
 | |
| +@@ -1717,7 +1665,7 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAl
 | |
| +   p->saveState.litProbs = 0;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| + {
 | |
| +   #ifndef _7ZIP_ST
 | |
| +   MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
 | |
| +@@ -1947,7 +1895,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, U
 | |
| +   return SZ_OK;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEnc_Init(CLzmaEnc *p)
 | |
| ++static void LzmaEnc_Init(CLzmaEnc *p)
 | |
| + {
 | |
| +   UInt32 i;
 | |
| +   p->state = 0;
 | |
| +@@ -2005,7 +1953,7 @@ void LzmaEnc_Init(CLzmaEnc *p)
 | |
| +   p->lpMask = (1 << p->lp) - 1;
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEnc_InitPrices(CLzmaEnc *p)
 | |
| ++static void LzmaEnc_InitPrices(CLzmaEnc *p)
 | |
| + {
 | |
| +   if (!p->fastMode)
 | |
| +   {
 | |
| +@@ -2037,26 +1985,6 @@ static SRes LzmaEnc_AllocAndInit(CLzmaEn
 | |
| +   return SZ_OK;
 | |
| + }
 | |
| + 
 | |
| +-static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
 | |
| +-    ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| +-{
 | |
| +-  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +-  p->matchFinderBase.stream = inStream;
 | |
| +-  p->needInit = 1;
 | |
| +-  p->rc.outStream = outStream;
 | |
| +-  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
 | |
| +-}
 | |
| +-
 | |
| +-SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
 | |
| +-    ISeqInStream *inStream, UInt32 keepWindowSize,
 | |
| +-    ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| +-{
 | |
| +-  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +-  p->matchFinderBase.stream = inStream;
 | |
| +-  p->needInit = 1;
 | |
| +-  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
 | |
| +-}
 | |
| +-
 | |
| + static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
 | |
| + {
 | |
| +   p->matchFinderBase.directInput = 1;
 | |
| +@@ -2064,7 +1992,7 @@ static void LzmaEnc_SetInputBuf(CLzmaEnc
 | |
| +   p->matchFinderBase.directInputRem = srcLen;
 | |
| + }
 | |
| + 
 | |
| +-SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
 | |
| ++static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
 | |
| +     UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| + {
 | |
| +   CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +@@ -2074,7 +2002,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p
 | |
| +   return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
 | |
| + }
 | |
| + 
 | |
| +-void LzmaEnc_Finish(CLzmaEncHandle pp)
 | |
| ++static void LzmaEnc_Finish(CLzmaEncHandle pp)
 | |
| + {
 | |
| +   #ifndef _7ZIP_ST
 | |
| +   CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +@@ -2107,53 +2035,6 @@ static size_t MyWrite(void *pp, const vo
 | |
| +   return size;
 | |
| + }
 | |
| + 
 | |
| +-
 | |
| +-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
 | |
| +-{
 | |
| +-  const CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +-  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
 | |
| +-}
 | |
| +-
 | |
| +-const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
 | |
| +-{
 | |
| +-  const CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +-  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
 | |
| +-}
 | |
| +-
 | |
| +-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
 | |
| +-    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
 | |
| +-{
 | |
| +-  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +-  UInt64 nowPos64;
 | |
| +-  SRes res;
 | |
| +-  CSeqOutStreamBuf outStream;
 | |
| +-
 | |
| +-  outStream.funcTable.Write = MyWrite;
 | |
| +-  outStream.data = dest;
 | |
| +-  outStream.rem = *destLen;
 | |
| +-  outStream.overflow = False;
 | |
| +-
 | |
| +-  p->writeEndMark = False;
 | |
| +-  p->finished = False;
 | |
| +-  p->result = SZ_OK;
 | |
| +-
 | |
| +-  if (reInit)
 | |
| +-    LzmaEnc_Init(p);
 | |
| +-  LzmaEnc_InitPrices(p);
 | |
| +-  nowPos64 = p->nowPos64;
 | |
| +-  RangeEnc_Init(&p->rc);
 | |
| +-  p->rc.outStream = &outStream.funcTable;
 | |
| +-
 | |
| +-  res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
 | |
| +-
 | |
| +-  *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
 | |
| +-  *destLen -= outStream.rem;
 | |
| +-  if (outStream.overflow)
 | |
| +-    return SZ_ERROR_OUTPUT_EOF;
 | |
| +-
 | |
| +-  return res;
 | |
| +-}
 | |
| +-
 | |
| + static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
 | |
| + {
 | |
| +   SRes res = SZ_OK;
 | |
| +@@ -2184,13 +2065,6 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p,
 | |
| +   return res;
 | |
| + }
 | |
| + 
 | |
| +-SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
 | |
| +-    ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| +-{
 | |
| +-  RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
 | |
| +-  return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
 | |
| +-}
 | |
| +-
 | |
| + SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
 | |
| + {
 | |
| +   CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| +@@ -2247,25 +2121,3 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp
 | |
| +     return SZ_ERROR_OUTPUT_EOF;
 | |
| +   return res;
 | |
| + }
 | |
| +-
 | |
| +-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
 | |
| +-    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
 | |
| +-    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| +-{
 | |
| +-  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
 | |
| +-  SRes res;
 | |
| +-  if (p == 0)
 | |
| +-    return SZ_ERROR_MEM;
 | |
| +-
 | |
| +-  res = LzmaEnc_SetProps(p, props);
 | |
| +-  if (res == SZ_OK)
 | |
| +-  {
 | |
| +-    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
 | |
| +-    if (res == SZ_OK)
 | |
| +-      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
 | |
| +-          writeEndMark, progress, alloc, allocBig);
 | |
| +-  }
 | |
| +-
 | |
| +-  LzmaEnc_Destroy(p, alloc, allocBig);
 | |
| +-  return res;
 | |
| +-}
 | |
| diff --git a/target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch b/target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch
 | |
| new file mode 100644
 | |
| index 0000000000..d8e5f2fc9b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/640-bridge-only-accept-EAP-locally.patch
 | |
| @@ -0,0 +1,82 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:18:54 +0200
 | |
| +Subject: bridge: only accept EAP locally
 | |
| +
 | |
| +When bridging, do not forward EAP frames to other ports, only deliver
 | |
| +them locally, regardless of the state.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +[add disable_eap_hack sysfs attribute]
 | |
| +Signed-off-by: Etienne Champetier <champetier.etienne@gmail.com>
 | |
| +---
 | |
| +
 | |
| +--- a/net/bridge/br_input.c
 | |
| ++++ b/net/bridge/br_input.c
 | |
| +@@ -107,10 +107,14 @@ int br_handle_frame_finish(struct net *n
 | |
| + 		}
 | |
| + 	}
 | |
| + 
 | |
| ++	BR_INPUT_SKB_CB(skb)->brdev = br->dev;
 | |
| ++
 | |
| ++	if (skb->protocol == htons(ETH_P_PAE) && !br->disable_eap_hack)
 | |
| ++		return br_pass_frame_up(skb);
 | |
| ++
 | |
| + 	if (state == BR_STATE_LEARNING)
 | |
| + 		goto drop;
 | |
| + 
 | |
| +-	BR_INPUT_SKB_CB(skb)->brdev = br->dev;
 | |
| + 	BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED);
 | |
| + 
 | |
| + 	if (IS_ENABLED(CONFIG_INET) &&
 | |
| +--- a/net/bridge/br_private.h
 | |
| ++++ b/net/bridge/br_private.h
 | |
| +@@ -404,6 +404,8 @@ struct net_bridge {
 | |
| + 	u16				group_fwd_mask;
 | |
| + 	u16				group_fwd_mask_required;
 | |
| + 
 | |
| ++	bool				disable_eap_hack;
 | |
| ++
 | |
| + 	/* STP */
 | |
| + 	bridge_id			designated_root;
 | |
| + 	bridge_id			bridge_id;
 | |
| +--- a/net/bridge/br_sysfs_br.c
 | |
| ++++ b/net/bridge/br_sysfs_br.c
 | |
| +@@ -164,6 +164,30 @@ static ssize_t group_fwd_mask_store(stru
 | |
| + }
 | |
| + static DEVICE_ATTR_RW(group_fwd_mask);
 | |
| + 
 | |
| ++static ssize_t disable_eap_hack_show(struct device *d,
 | |
| ++				   struct device_attribute *attr,
 | |
| ++				   char *buf)
 | |
| ++{
 | |
| ++	struct net_bridge *br = to_bridge(d);
 | |
| ++	return sprintf(buf, "%u\n", br->disable_eap_hack);
 | |
| ++}
 | |
| ++
 | |
| ++static int set_disable_eap_hack(struct net_bridge *br, unsigned long val)
 | |
| ++{
 | |
| ++	br->disable_eap_hack = !!val;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static ssize_t disable_eap_hack_store(struct device *d,
 | |
| ++				    struct device_attribute *attr,
 | |
| ++				    const char *buf,
 | |
| ++				    size_t len)
 | |
| ++{
 | |
| ++	return store_bridge_parm(d, buf, len, set_disable_eap_hack);
 | |
| ++}
 | |
| ++static DEVICE_ATTR_RW(disable_eap_hack);
 | |
| ++
 | |
| + static ssize_t priority_show(struct device *d, struct device_attribute *attr,
 | |
| + 			     char *buf)
 | |
| + {
 | |
| +@@ -849,6 +873,7 @@ static struct attribute *bridge_attrs[]
 | |
| + 	&dev_attr_ageing_time.attr,
 | |
| + 	&dev_attr_stp_state.attr,
 | |
| + 	&dev_attr_group_fwd_mask.attr,
 | |
| ++	&dev_attr_disable_eap_hack.attr,
 | |
| + 	&dev_attr_priority.attr,
 | |
| + 	&dev_attr_bridge_id.attr,
 | |
| + 	&dev_attr_root_id.attr,
 | |
| diff --git a/target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch b/target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2d3fe01a75
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/645-netfilter-connmark-introduce-set-dscpmark.patch
 | |
| @@ -0,0 +1,212 @@
 | |
| +From eda40b8c8c82e0f2789d6bc8bf63846dce2e8f32 Mon Sep 17 00:00:00 2001
 | |
| +From: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 | |
| +Date: Sat, 23 Mar 2019 09:29:49 +0000
 | |
| +Subject: [PATCH] netfilter: connmark: introduce set-dscpmark
 | |
| +
 | |
| +set-dscpmark is a method of storing the DSCP of an ip packet into
 | |
| +conntrack mark.  In combination with a suitable tc filter action
 | |
| +(act_ctinfo) DSCP values are able to be stored in the mark on egress and
 | |
| +restored on ingress across links that otherwise alter or bleach DSCP.
 | |
| +
 | |
| +This is useful for qdiscs such as CAKE which are able to shape according
 | |
| +to policies based on DSCP.
 | |
| +
 | |
| +Ingress classification is traditionally a challenging task since
 | |
| +iptables rules haven't yet run and tc filter/eBPF programs are pre-NAT
 | |
| +lookups, hence are unable to see internal IPv4 addresses as used on the
 | |
| +typical home masquerading gateway.
 | |
| +
 | |
| +x_tables CONNMARK set-dscpmark target solves the problem of storing the
 | |
| +DSCP to the conntrack mark in a way suitable for the new act_ctinfo tc
 | |
| +action to restore.
 | |
| +
 | |
| +The set-dscpmark option accepts 2 parameters, a 32bit 'dscpmask' and a
 | |
| +32bit 'statemask'.  The dscp mask must be 6 contiguous bits and
 | |
| +represents the area where the DSCP will be stored in the connmark.  The
 | |
| +state mask is a minimum 1 bit length mask that must not overlap with the
 | |
| +dscpmask.  It represents a flag which is set when the DSCP has been
 | |
| +stored in the conntrack mark. This is useful to implement a 'one shot'
 | |
| +iptables based classification where the 'complicated' iptables rules are
 | |
| +only run once to classify the connection on initial (egress) packet and
 | |
| +subsequent packets are all marked/restored with the same DSCP.  A state
 | |
| +mask of zero disables the setting of a status bit/s.
 | |
| +
 | |
| +example syntax with a suitably modified iptables user space application:
 | |
| +
 | |
| +iptables -A QOS_MARK_eth0 -t mangle -j CONNMARK --set-dscpmark 0xfc000000/0x01000000
 | |
| +
 | |
| +Would store the DSCP in the top 6 bits of the 32bit mark field, and use
 | |
| +the LSB of the top byte as the 'DSCP has been stored' marker.
 | |
| +
 | |
| +|----0xFC----conntrack mark----000000---|
 | |
| +| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
 | |
| +| DSCP       | unused | flag  |unused   |
 | |
| +|-----------------------0x01---000000---|
 | |
| +      ^                   ^
 | |
| +      |                   |
 | |
| +      ---|             Conditional flag
 | |
| +         |             set this when dscp
 | |
| +|-ip diffserv-|        stored in mark
 | |
| +| 6 bits      |
 | |
| +|-------------|
 | |
| +
 | |
| +an identically configured tc action to restore looks like:
 | |
| +
 | |
| +tc filter show dev eth0 ingress
 | |
| +filter parent ffff: protocol all pref 10 u32 chain 0
 | |
| +filter parent ffff: protocol all pref 10 u32 chain 0 fh 800: ht divisor 1
 | |
| +filter parent ffff: protocol all pref 10 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1: not_in_hw
 | |
| +  match 00000000/00000000 at 0
 | |
| +	action order 1: ctinfo zone 0 pipe
 | |
| +	 index 2 ref 1 bind 1 dscp 0xfc000000/0x1000000
 | |
| +
 | |
| +	action order 2: mirred (Egress Redirect to device ifb4eth0) stolen
 | |
| +	index 1 ref 1 bind 1
 | |
| +
 | |
| +|----0xFC----conntrack mark----000000---|
 | |
| +| Bits 31-26 | bit 25 | bit24 |~~~ Bit 0|
 | |
| +| DSCP       | unused | flag  |unused   |
 | |
| +|-----------------------0x01---000000---|
 | |
| +      |                   |
 | |
| +      |                   |
 | |
| +      ---|             Conditional flag
 | |
| +         v             only restore if set
 | |
| +|-ip diffserv-|
 | |
| +| 6 bits      |
 | |
| +|-------------|
 | |
| +
 | |
| +Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
 | |
| +---
 | |
| + include/uapi/linux/netfilter/xt_connmark.h | 10 ++++
 | |
| + net/netfilter/xt_connmark.c                | 55 ++++++++++++++++++----
 | |
| + 2 files changed, 57 insertions(+), 8 deletions(-)
 | |
| +
 | |
| +--- a/include/uapi/linux/netfilter/xt_connmark.h
 | |
| ++++ b/include/uapi/linux/netfilter/xt_connmark.h
 | |
| +@@ -20,6 +20,11 @@ enum {
 | |
| + };
 | |
| + 
 | |
| + enum {
 | |
| ++	XT_CONNMARK_VALUE =	(1 << 0),
 | |
| ++	XT_CONNMARK_DSCP = 	(1 << 1)
 | |
| ++};
 | |
| ++
 | |
| ++enum {
 | |
| + 	D_SHIFT_LEFT = 0,
 | |
| + 	D_SHIFT_RIGHT,
 | |
| + };
 | |
| +@@ -34,6 +39,11 @@ struct xt_connmark_tginfo2 {
 | |
| + 	__u8 shift_dir, shift_bits, mode;
 | |
| + };
 | |
| + 
 | |
| ++struct xt_connmark_tginfo3 {
 | |
| ++	__u32 ctmark, ctmask, nfmask;
 | |
| ++	__u8 shift_dir, shift_bits, mode, func;
 | |
| ++};
 | |
| ++
 | |
| + struct xt_connmark_mtinfo1 {
 | |
| + 	__u32 mark, mask;
 | |
| + 	__u8 invert;
 | |
| +--- a/net/netfilter/xt_connmark.c
 | |
| ++++ b/net/netfilter/xt_connmark.c
 | |
| +@@ -24,12 +24,13 @@ MODULE_ALIAS("ipt_connmark");
 | |
| + MODULE_ALIAS("ip6t_connmark");
 | |
| + 
 | |
| + static unsigned int
 | |
| +-connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo2 *info)
 | |
| ++connmark_tg_shift(struct sk_buff *skb, const struct xt_connmark_tginfo3 *info)
 | |
| + {
 | |
| + 	enum ip_conntrack_info ctinfo;
 | |
| + 	u_int32_t new_targetmark;
 | |
| + 	struct nf_conn *ct;
 | |
| + 	u_int32_t newmark;
 | |
| ++	u_int8_t dscp;
 | |
| + 
 | |
| + 	ct = nf_ct_get(skb, &ctinfo);
 | |
| + 	if (ct == NULL)
 | |
| +@@ -37,12 +38,24 @@ connmark_tg_shift(struct sk_buff *skb, c
 | |
| + 
 | |
| + 	switch (info->mode) {
 | |
| + 	case XT_CONNMARK_SET:
 | |
| +-		newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
 | |
| +-		if (info->shift_dir == D_SHIFT_RIGHT)
 | |
| +-			newmark >>= info->shift_bits;
 | |
| +-		else
 | |
| +-			newmark <<= info->shift_bits;
 | |
| ++		newmark = ct->mark;
 | |
| ++		if (info->func & XT_CONNMARK_VALUE) {
 | |
| ++			newmark = (newmark & ~info->ctmask) ^ info->ctmark;
 | |
| ++			if (info->shift_dir == D_SHIFT_RIGHT)
 | |
| ++				newmark >>= info->shift_bits;
 | |
| ++			else
 | |
| ++				newmark <<= info->shift_bits;
 | |
| ++		} else if (info->func & XT_CONNMARK_DSCP) {
 | |
| ++			if (skb->protocol == htons(ETH_P_IP))
 | |
| ++				dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
 | |
| ++			else if (skb->protocol == htons(ETH_P_IPV6))
 | |
| ++				dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
 | |
| ++			else	/* protocol doesn't have diffserv */
 | |
| ++				break;
 | |
| + 
 | |
| ++			newmark = (newmark & ~info->ctmark) |
 | |
| ++				  (info->ctmask | (dscp << info->shift_bits));
 | |
| ++		}
 | |
| + 		if (ct->mark != newmark) {
 | |
| + 			ct->mark = newmark;
 | |
| + 			nf_conntrack_event_cache(IPCT_MARK, ct);
 | |
| +@@ -81,20 +94,36 @@ static unsigned int
 | |
| + connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
 | |
| + {
 | |
| + 	const struct xt_connmark_tginfo1 *info = par->targinfo;
 | |
| +-	const struct xt_connmark_tginfo2 info2 = {
 | |
| ++	const struct xt_connmark_tginfo3 info3 = {
 | |
| + 		.ctmark	= info->ctmark,
 | |
| + 		.ctmask	= info->ctmask,
 | |
| + 		.nfmask	= info->nfmask,
 | |
| + 		.mode	= info->mode,
 | |
| ++		.func	= XT_CONNMARK_VALUE
 | |
| + 	};
 | |
| + 
 | |
| +-	return connmark_tg_shift(skb, &info2);
 | |
| ++	return connmark_tg_shift(skb, &info3);
 | |
| + }
 | |
| + 
 | |
| + static unsigned int
 | |
| + connmark_tg_v2(struct sk_buff *skb, const struct xt_action_param *par)
 | |
| + {
 | |
| + 	const struct xt_connmark_tginfo2 *info = par->targinfo;
 | |
| ++	const struct xt_connmark_tginfo3 info3 = {
 | |
| ++		.ctmark	= info->ctmark,
 | |
| ++		.ctmask	= info->ctmask,
 | |
| ++		.nfmask	= info->nfmask,
 | |
| ++		.mode	= info->mode,
 | |
| ++		.func	= XT_CONNMARK_VALUE
 | |
| ++	};
 | |
| ++
 | |
| ++	return connmark_tg_shift(skb, &info3);
 | |
| ++}
 | |
| ++
 | |
| ++static unsigned int
 | |
| ++connmark_tg_v3(struct sk_buff *skb, const struct xt_action_param *par)
 | |
| ++{
 | |
| ++	const struct xt_connmark_tginfo3 *info = par->targinfo;
 | |
| + 
 | |
| + 	return connmark_tg_shift(skb, info);
 | |
| + }
 | |
| +@@ -165,6 +194,16 @@ static struct xt_target connmark_tg_reg[
 | |
| + 		.targetsize     = sizeof(struct xt_connmark_tginfo2),
 | |
| + 		.destroy        = connmark_tg_destroy,
 | |
| + 		.me             = THIS_MODULE,
 | |
| ++	},
 | |
| ++	{
 | |
| ++		.name           = "CONNMARK",
 | |
| ++		.revision       = 3,
 | |
| ++		.family         = NFPROTO_UNSPEC,
 | |
| ++		.checkentry     = connmark_tg_check,
 | |
| ++		.target         = connmark_tg_v3,
 | |
| ++		.targetsize     = sizeof(struct xt_connmark_tginfo3),
 | |
| ++		.destroy        = connmark_tg_destroy,
 | |
| ++		.me             = THIS_MODULE,
 | |
| + 	}
 | |
| + };
 | |
| + 
 | |
| diff --git a/target/linux/generic/hack-5.10/650-netfilter-add-xt_FLOWOFFLOAD-target.patch b/target/linux/generic/hack-5.10/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
 | |
| new file mode 100644
 | |
| index 0000000000..97aa7a673b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/650-netfilter-add-xt_FLOWOFFLOAD-target.patch
 | |
| @@ -0,0 +1,820 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Tue, 20 Feb 2018 15:56:02 +0100
 | |
| +Subject: [PATCH] netfilter: add xt_FLOWOFFLOAD target
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + create mode 100644 net/netfilter/xt_OFFLOAD.c
 | |
| +
 | |
| +--- a/net/ipv4/netfilter/Kconfig
 | |
| ++++ b/net/ipv4/netfilter/Kconfig
 | |
| +@@ -56,8 +56,6 @@ config NF_TABLES_ARP
 | |
| + 	help
 | |
| + 	  This option enables the ARP support for nf_tables.
 | |
| + 
 | |
| +-endif # NF_TABLES
 | |
| +-
 | |
| + config NF_FLOW_TABLE_IPV4
 | |
| + 	tristate "Netfilter flow table IPv4 module"
 | |
| + 	depends on NF_FLOW_TABLE
 | |
| +@@ -66,6 +64,8 @@ config NF_FLOW_TABLE_IPV4
 | |
| + 
 | |
| + 	  To compile it as a module, choose M here.
 | |
| + 
 | |
| ++endif # NF_TABLES
 | |
| ++
 | |
| + config NF_DUP_IPV4
 | |
| + 	tristate "Netfilter IPv4 packet duplication to alternate destination"
 | |
| + 	depends on !NF_CONNTRACK || NF_CONNTRACK
 | |
| +--- a/net/ipv6/netfilter/Kconfig
 | |
| ++++ b/net/ipv6/netfilter/Kconfig
 | |
| +@@ -45,7 +45,6 @@ config NFT_FIB_IPV6
 | |
| + 	  multicast or blackhole.
 | |
| + 
 | |
| + endif # NF_TABLES_IPV6
 | |
| +-endif # NF_TABLES
 | |
| + 
 | |
| + config NF_FLOW_TABLE_IPV6
 | |
| + 	tristate "Netfilter flow table IPv6 module"
 | |
| +@@ -55,6 +54,8 @@ config NF_FLOW_TABLE_IPV6
 | |
| + 
 | |
| + 	  To compile it as a module, choose M here.
 | |
| + 
 | |
| ++endif # NF_TABLES
 | |
| ++
 | |
| + config NF_DUP_IPV6
 | |
| + 	tristate "Netfilter IPv6 packet duplication to alternate destination"
 | |
| + 	depends on !NF_CONNTRACK || NF_CONNTRACK
 | |
| +--- a/net/netfilter/Kconfig
 | |
| ++++ b/net/netfilter/Kconfig
 | |
| +@@ -683,8 +683,6 @@ config NFT_FIB_NETDEV
 | |
| + 
 | |
| + endif # NF_TABLES_NETDEV
 | |
| + 
 | |
| +-endif # NF_TABLES
 | |
| +-
 | |
| + config NF_FLOW_TABLE_INET
 | |
| + 	tristate "Netfilter flow table mixed IPv4/IPv6 module"
 | |
| + 	depends on NF_FLOW_TABLE
 | |
| +@@ -693,11 +691,12 @@ config NF_FLOW_TABLE_INET
 | |
| + 
 | |
| + 	  To compile it as a module, choose M here.
 | |
| + 
 | |
| ++endif # NF_TABLES
 | |
| ++
 | |
| + config NF_FLOW_TABLE
 | |
| + 	tristate "Netfilter flow table module"
 | |
| + 	depends on NETFILTER_INGRESS
 | |
| + 	depends on NF_CONNTRACK
 | |
| +-	depends on NF_TABLES
 | |
| + 	help
 | |
| + 	  This option adds the flow table core infrastructure.
 | |
| + 
 | |
| +@@ -977,6 +976,15 @@ config NETFILTER_XT_TARGET_NOTRACK
 | |
| + 	depends on NETFILTER_ADVANCED
 | |
| + 	select NETFILTER_XT_TARGET_CT
 | |
| + 
 | |
| ++config NETFILTER_XT_TARGET_FLOWOFFLOAD
 | |
| ++	tristate '"FLOWOFFLOAD" target support'
 | |
| ++	depends on NF_FLOW_TABLE
 | |
| ++	depends on NETFILTER_INGRESS
 | |
| ++	help
 | |
| ++	  This option adds a `FLOWOFFLOAD' target, which uses the nf_flow_offload
 | |
| ++	  module to speed up processing of packets by bypassing the usual
 | |
| ++	  netfilter chains
 | |
| ++
 | |
| + config NETFILTER_XT_TARGET_RATEEST
 | |
| + 	tristate '"RATEEST" target support'
 | |
| + 	depends on NETFILTER_ADVANCED
 | |
| +--- a/net/netfilter/Makefile
 | |
| ++++ b/net/netfilter/Makefile
 | |
| +@@ -145,6 +145,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CLASSIF
 | |
| + obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
 | |
| + obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
 | |
| + obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
 | |
| ++obj-$(CONFIG_NETFILTER_XT_TARGET_FLOWOFFLOAD) += xt_FLOWOFFLOAD.o
 | |
| + obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
 | |
| + obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK) += xt_HMARK.o
 | |
| + obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
 | |
| +--- /dev/null
 | |
| ++++ b/net/netfilter/xt_FLOWOFFLOAD.c
 | |
| +@@ -0,0 +1,658 @@
 | |
| ++/*
 | |
| ++ * Copyright (C) 2018-2021 Felix Fietkau <nbd@nbd.name>
 | |
| ++ *
 | |
| ++ * This program is free software; you can redistribute it and/or modify
 | |
| ++ * it under the terms of the GNU General Public License version 2 as
 | |
| ++ * published by the Free Software Foundation.
 | |
| ++ */
 | |
| ++#include <linux/module.h>
 | |
| ++#include <linux/init.h>
 | |
| ++#include <linux/netfilter.h>
 | |
| ++#include <linux/netfilter/xt_FLOWOFFLOAD.h>
 | |
| ++#include <net/ip.h>
 | |
| ++#include <net/netfilter/nf_conntrack.h>
 | |
| ++#include <net/netfilter/nf_conntrack_extend.h>
 | |
| ++#include <net/netfilter/nf_conntrack_helper.h>
 | |
| ++#include <net/netfilter/nf_flow_table.h>
 | |
| ++
 | |
| ++struct xt_flowoffload_hook {
 | |
| ++	struct hlist_node list;
 | |
| ++	struct nf_hook_ops ops;
 | |
| ++	struct net *net;
 | |
| ++	bool registered;
 | |
| ++	bool used;
 | |
| ++};
 | |
| ++
 | |
| ++struct xt_flowoffload_table {
 | |
| ++	struct nf_flowtable ft;
 | |
| ++	struct hlist_head hooks;
 | |
| ++	struct delayed_work work;
 | |
| ++};
 | |
| ++
 | |
| ++static DEFINE_SPINLOCK(hooks_lock);
 | |
| ++
 | |
| ++struct xt_flowoffload_table flowtable[2];
 | |
| ++
 | |
| ++static unsigned int
 | |
| ++xt_flowoffload_net_hook(void *priv, struct sk_buff *skb,
 | |
| ++			const struct nf_hook_state *state)
 | |
| ++{
 | |
| ++	struct nf_flowtable *ft = priv;
 | |
| ++
 | |
| ++	if (!atomic_read(&ft->rhashtable.nelems))
 | |
| ++		return NF_ACCEPT;
 | |
| ++
 | |
| ++	switch (skb->protocol) {
 | |
| ++	case htons(ETH_P_IP):
 | |
| ++		return nf_flow_offload_ip_hook(priv, skb, state);
 | |
| ++	case htons(ETH_P_IPV6):
 | |
| ++		return nf_flow_offload_ipv6_hook(priv, skb, state);
 | |
| ++	}
 | |
| ++
 | |
| ++	return NF_ACCEPT;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++xt_flowoffload_create_hook(struct xt_flowoffload_table *table,
 | |
| ++			   struct net_device *dev)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_hook *hook;
 | |
| ++	struct nf_hook_ops *ops;
 | |
| ++
 | |
| ++	hook = kzalloc(sizeof(*hook), GFP_ATOMIC);
 | |
| ++	if (!hook)
 | |
| ++		return -ENOMEM;
 | |
| ++
 | |
| ++	ops = &hook->ops;
 | |
| ++	ops->pf = NFPROTO_NETDEV;
 | |
| ++	ops->hooknum = NF_NETDEV_INGRESS;
 | |
| ++	ops->priority = 10;
 | |
| ++	ops->priv = &table->ft;
 | |
| ++	ops->hook = xt_flowoffload_net_hook;
 | |
| ++	ops->dev = dev;
 | |
| ++
 | |
| ++	hlist_add_head(&hook->list, &table->hooks);
 | |
| ++	mod_delayed_work(system_power_efficient_wq, &table->work, 0);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static struct xt_flowoffload_hook *
 | |
| ++flow_offload_lookup_hook(struct xt_flowoffload_table *table,
 | |
| ++			 struct net_device *dev)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_hook *hook;
 | |
| ++
 | |
| ++	hlist_for_each_entry(hook, &table->hooks, list) {
 | |
| ++		if (hook->ops.dev == dev)
 | |
| ++			return hook;
 | |
| ++	}
 | |
| ++
 | |
| ++	return NULL;
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++xt_flowoffload_check_device(struct xt_flowoffload_table *table,
 | |
| ++			    struct net_device *dev)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_hook *hook;
 | |
| ++
 | |
| ++	if (!dev)
 | |
| ++		return;
 | |
| ++
 | |
| ++	spin_lock_bh(&hooks_lock);
 | |
| ++	hook = flow_offload_lookup_hook(table, dev);
 | |
| ++	if (hook)
 | |
| ++		hook->used = true;
 | |
| ++	else
 | |
| ++		xt_flowoffload_create_hook(table, dev);
 | |
| ++	spin_unlock_bh(&hooks_lock);
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++xt_flowoffload_register_hooks(struct xt_flowoffload_table *table)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_hook *hook;
 | |
| ++
 | |
| ++restart:
 | |
| ++	hlist_for_each_entry(hook, &table->hooks, list) {
 | |
| ++		if (hook->registered)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		hook->registered = true;
 | |
| ++		hook->net = dev_net(hook->ops.dev);
 | |
| ++		spin_unlock_bh(&hooks_lock);
 | |
| ++		nf_register_net_hook(hook->net, &hook->ops);
 | |
| ++		if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
 | |
| ++			table->ft.type->setup(&table->ft, hook->ops.dev,
 | |
| ++					      FLOW_BLOCK_BIND);
 | |
| ++		spin_lock_bh(&hooks_lock);
 | |
| ++		goto restart;
 | |
| ++	}
 | |
| ++
 | |
| ++}
 | |
| ++
 | |
| ++static bool
 | |
| ++xt_flowoffload_cleanup_hooks(struct xt_flowoffload_table *table)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_hook *hook;
 | |
| ++	bool active = false;
 | |
| ++
 | |
| ++restart:
 | |
| ++	spin_lock_bh(&hooks_lock);
 | |
| ++	hlist_for_each_entry(hook, &table->hooks, list) {
 | |
| ++		if (hook->used || !hook->registered) {
 | |
| ++			active = true;
 | |
| ++			continue;
 | |
| ++		}
 | |
| ++
 | |
| ++		hlist_del(&hook->list);
 | |
| ++		spin_unlock_bh(&hooks_lock);
 | |
| ++		if (table->ft.flags & NF_FLOWTABLE_HW_OFFLOAD)
 | |
| ++			table->ft.type->setup(&table->ft, hook->ops.dev,
 | |
| ++					      FLOW_BLOCK_UNBIND);
 | |
| ++		nf_unregister_net_hook(hook->net, &hook->ops);
 | |
| ++		kfree(hook);
 | |
| ++		goto restart;
 | |
| ++	}
 | |
| ++	spin_unlock_bh(&hooks_lock);
 | |
| ++
 | |
| ++	return active;
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++xt_flowoffload_check_hook(struct flow_offload *flow, void *data)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_table *table = data;
 | |
| ++	struct flow_offload_tuple *tuple0 = &flow->tuplehash[0].tuple;
 | |
| ++	struct flow_offload_tuple *tuple1 = &flow->tuplehash[1].tuple;
 | |
| ++	struct xt_flowoffload_hook *hook;
 | |
| ++
 | |
| ++	spin_lock_bh(&hooks_lock);
 | |
| ++	hlist_for_each_entry(hook, &table->hooks, list) {
 | |
| ++		if (hook->ops.dev->ifindex != tuple0->iifidx &&
 | |
| ++		    hook->ops.dev->ifindex != tuple1->iifidx)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		hook->used = true;
 | |
| ++	}
 | |
| ++	spin_unlock_bh(&hooks_lock);
 | |
| ++
 | |
| ++	cond_resched();
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++xt_flowoffload_hook_work(struct work_struct *work)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_table *table;
 | |
| ++	struct xt_flowoffload_hook *hook;
 | |
| ++	int err;
 | |
| ++
 | |
| ++	table = container_of(work, struct xt_flowoffload_table, work.work);
 | |
| ++
 | |
| ++	spin_lock_bh(&hooks_lock);
 | |
| ++	xt_flowoffload_register_hooks(table);
 | |
| ++	hlist_for_each_entry(hook, &table->hooks, list)
 | |
| ++		hook->used = false;
 | |
| ++	spin_unlock_bh(&hooks_lock);
 | |
| ++
 | |
| ++	err = nf_flow_table_iterate(&table->ft, xt_flowoffload_check_hook,
 | |
| ++				    table);
 | |
| ++	if (err && err != -EAGAIN)
 | |
| ++		goto out;
 | |
| ++
 | |
| ++	if (!xt_flowoffload_cleanup_hooks(table))
 | |
| ++		return;
 | |
| ++
 | |
| ++out:
 | |
| ++	queue_delayed_work(system_power_efficient_wq, &table->work, HZ);
 | |
| ++}
 | |
| ++
 | |
| ++static bool
 | |
| ++xt_flowoffload_skip(struct sk_buff *skb, int family)
 | |
| ++{
 | |
| ++	if (skb_sec_path(skb))
 | |
| ++		return true;
 | |
| ++
 | |
| ++	if (family == NFPROTO_IPV4) {
 | |
| ++		const struct ip_options *opt = &(IPCB(skb)->opt);
 | |
| ++
 | |
| ++		if (unlikely(opt->optlen))
 | |
| ++			return true;
 | |
| ++	}
 | |
| ++
 | |
| ++	return false;
 | |
| ++}
 | |
| ++
 | |
| ++static bool flow_is_valid_ether_device(const struct net_device *dev)
 | |
| ++{
 | |
| ++	if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
 | |
| ++	    dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
 | |
| ++		return false;
 | |
| ++
 | |
| ++	return true;
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++xt_flowoffload_route_check_path(struct nf_flow_route *route,
 | |
| ++				const struct nf_conn *ct,
 | |
| ++				enum ip_conntrack_dir dir,
 | |
| ++				struct net_device **out_dev)
 | |
| ++{
 | |
| ++	const struct dst_entry *dst = route->tuple[dir].dst;
 | |
| ++	const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
 | |
| ++	struct net_device_path_stack stack;
 | |
| ++	enum net_device_path_type prev_type;
 | |
| ++	struct net_device *dev = dst->dev;
 | |
| ++	struct neighbour *n;
 | |
| ++	bool last = false;
 | |
| ++	u8 nud_state;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	route->tuple[!dir].in.ifindex = dev->ifindex;
 | |
| ++	route->tuple[dir].out.ifindex = dev->ifindex;
 | |
| ++
 | |
| ++	if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_XFRM)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if ((dev->flags & IFF_LOOPBACK) ||
 | |
| ++	    dev->type != ARPHRD_ETHER || dev->addr_len != ETH_ALEN ||
 | |
| ++	    !is_valid_ether_addr(dev->dev_addr))
 | |
| ++		return;
 | |
| ++
 | |
| ++	n = dst_neigh_lookup(dst, daddr);
 | |
| ++	if (!n)
 | |
| ++		return;
 | |
| ++
 | |
| ++	read_lock_bh(&n->lock);
 | |
| ++	nud_state = n->nud_state;
 | |
| ++	memcpy(route->tuple[dir].out.h_dest, n->ha, ETH_ALEN);
 | |
| ++	read_unlock_bh(&n->lock);
 | |
| ++	neigh_release(n);
 | |
| ++
 | |
| ++	if (!(nud_state & NUD_VALID))
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (dev_fill_forward_path(dev, route->tuple[dir].out.h_dest, &stack) ||
 | |
| ++	    !stack.num_paths)
 | |
| ++		return;
 | |
| ++
 | |
| ++	prev_type = DEV_PATH_ETHERNET;
 | |
| ++	for (i = 0; i <= stack.num_paths; i++) {
 | |
| ++		const struct net_device_path *path = &stack.path[i];
 | |
| ++		int n_encaps = route->tuple[!dir].in.num_encaps;
 | |
| ++
 | |
| ++		dev = (struct net_device *)path->dev;
 | |
| ++		if (flow_is_valid_ether_device(dev)) {
 | |
| ++			if (route->tuple[dir].xmit_type != FLOW_OFFLOAD_XMIT_DIRECT) {
 | |
| ++				memcpy(route->tuple[dir].out.h_source,
 | |
| ++				       dev->dev_addr, ETH_ALEN);
 | |
| ++				route->tuple[dir].out.ifindex = dev->ifindex;
 | |
| ++			}
 | |
| ++			route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
 | |
| ++		}
 | |
| ++
 | |
| ++		switch (path->type) {
 | |
| ++		case DEV_PATH_PPPOE:
 | |
| ++		case DEV_PATH_VLAN:
 | |
| ++			if (n_encaps >= NF_FLOW_TABLE_ENCAP_MAX ||
 | |
| ++			    i == stack.num_paths) {
 | |
| ++				last = true;
 | |
| ++				break;
 | |
| ++			}
 | |
| ++
 | |
| ++			route->tuple[!dir].in.num_encaps++;
 | |
| ++			route->tuple[!dir].in.encap[n_encaps].id = path->encap.id;
 | |
| ++			route->tuple[!dir].in.encap[n_encaps].proto = path->encap.proto;
 | |
| ++			if (path->type == DEV_PATH_PPPOE)
 | |
| ++				memcpy(route->tuple[dir].out.h_dest,
 | |
| ++				       path->encap.h_dest, ETH_ALEN);
 | |
| ++			break;
 | |
| ++		case DEV_PATH_BRIDGE:
 | |
| ++			switch (path->bridge.vlan_mode) {
 | |
| ++			case DEV_PATH_BR_VLAN_TAG:
 | |
| ++				if (n_encaps >= NF_FLOW_TABLE_ENCAP_MAX ||
 | |
| ++				    i == stack.num_paths) {
 | |
| ++					last = true;
 | |
| ++					break;
 | |
| ++				}
 | |
| ++
 | |
| ++				route->tuple[!dir].in.num_encaps++;
 | |
| ++				route->tuple[!dir].in.encap[n_encaps].id =
 | |
| ++					path->bridge.vlan_id;
 | |
| ++				route->tuple[!dir].in.encap[n_encaps].proto =
 | |
| ++					path->bridge.vlan_proto;
 | |
| ++				break;
 | |
| ++			case DEV_PATH_BR_VLAN_UNTAG:
 | |
| ++				route->tuple[!dir].in.num_encaps--;
 | |
| ++				break;
 | |
| ++			case DEV_PATH_BR_VLAN_UNTAG_HW:
 | |
| ++				route->tuple[!dir].in.ingress_vlans |= BIT(n_encaps - 1);
 | |
| ++				break;
 | |
| ++			case DEV_PATH_BR_VLAN_KEEP:
 | |
| ++				break;
 | |
| ++			}
 | |
| ++			break;
 | |
| ++		default:
 | |
| ++			last = true;
 | |
| ++			break;
 | |
| ++		}
 | |
| ++
 | |
| ++		if (last)
 | |
| ++			break;
 | |
| ++	}
 | |
| ++
 | |
| ++	*out_dev = dev;
 | |
| ++	route->tuple[dir].out.hw_ifindex = dev->ifindex;
 | |
| ++	route->tuple[!dir].in.ifindex = dev->ifindex;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++xt_flowoffload_route_dir(struct nf_flow_route *route, const struct nf_conn *ct,
 | |
| ++			 enum ip_conntrack_dir dir,
 | |
| ++			 const struct xt_action_param *par, int ifindex)
 | |
| ++{
 | |
| ++	struct dst_entry *dst = NULL;
 | |
| ++	struct flowi fl;
 | |
| ++
 | |
| ++	memset(&fl, 0, sizeof(fl));
 | |
| ++	switch (xt_family(par)) {
 | |
| ++	case NFPROTO_IPV4:
 | |
| ++		fl.u.ip4.daddr = ct->tuplehash[!dir].tuple.src.u3.ip;
 | |
| ++		fl.u.ip4.flowi4_oif = ifindex;
 | |
| ++		break;
 | |
| ++	case NFPROTO_IPV6:
 | |
| ++		fl.u.ip6.saddr = ct->tuplehash[!dir].tuple.dst.u3.in6;
 | |
| ++		fl.u.ip6.daddr = ct->tuplehash[!dir].tuple.src.u3.in6;
 | |
| ++		fl.u.ip6.flowi6_oif = ifindex;
 | |
| ++		break;
 | |
| ++	}
 | |
| ++
 | |
| ++	nf_route(xt_net(par), &dst, &fl, false, xt_family(par));
 | |
| ++	if (!dst)
 | |
| ++		return -ENOENT;
 | |
| ++
 | |
| ++	route->tuple[dir].dst = dst;
 | |
| ++	if (dst_xfrm(dst))
 | |
| ++		route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_XFRM;
 | |
| ++	else
 | |
| ++		route->tuple[dir].xmit_type = FLOW_OFFLOAD_XMIT_NEIGH;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++xt_flowoffload_route(struct sk_buff *skb, const struct nf_conn *ct,
 | |
| ++		     const struct xt_action_param *par,
 | |
| ++		     struct nf_flow_route *route, enum ip_conntrack_dir dir,
 | |
| ++		     struct net_device **dev)
 | |
| ++{
 | |
| ++	int ret;
 | |
| ++
 | |
| ++	ret = xt_flowoffload_route_dir(route, ct, dir, par,
 | |
| ++				       dev[dir]->ifindex);
 | |
| ++	if (ret)
 | |
| ++		return ret;
 | |
| ++
 | |
| ++	ret = xt_flowoffload_route_dir(route, ct, !dir, par,
 | |
| ++				       dev[!dir]->ifindex);
 | |
| ++	if (ret)
 | |
| ++		return ret;
 | |
| ++
 | |
| ++	xt_flowoffload_route_check_path(route, ct, dir, &dev[!dir]);
 | |
| ++	xt_flowoffload_route_check_path(route, ct, !dir, &dev[dir]);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static unsigned int
 | |
| ++flowoffload_tg(struct sk_buff *skb, const struct xt_action_param *par)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_table *table;
 | |
| ++	const struct xt_flowoffload_target_info *info = par->targinfo;
 | |
| ++	struct tcphdr _tcph, *tcph = NULL;
 | |
| ++	enum ip_conntrack_info ctinfo;
 | |
| ++	enum ip_conntrack_dir dir;
 | |
| ++	struct nf_flow_route route = {};
 | |
| ++	struct flow_offload *flow = NULL;
 | |
| ++	struct net_device *devs[2] = {};
 | |
| ++	struct nf_conn *ct;
 | |
| ++	struct net *net;
 | |
| ++
 | |
| ++	if (xt_flowoffload_skip(skb, xt_family(par)))
 | |
| ++		return XT_CONTINUE;
 | |
| ++
 | |
| ++	ct = nf_ct_get(skb, &ctinfo);
 | |
| ++	if (ct == NULL)
 | |
| ++		return XT_CONTINUE;
 | |
| ++
 | |
| ++	switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) {
 | |
| ++	case IPPROTO_TCP:
 | |
| ++		if (ct->proto.tcp.state != TCP_CONNTRACK_ESTABLISHED)
 | |
| ++			return XT_CONTINUE;
 | |
| ++
 | |
| ++		tcph = skb_header_pointer(skb, par->thoff,
 | |
| ++					  sizeof(_tcph), &_tcph);
 | |
| ++		if (unlikely(!tcph || tcph->fin || tcph->rst))
 | |
| ++			return XT_CONTINUE;
 | |
| ++		break;
 | |
| ++	case IPPROTO_UDP:
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return XT_CONTINUE;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) ||
 | |
| ++	    ct->status & IPS_SEQ_ADJUST)
 | |
| ++		return XT_CONTINUE;
 | |
| ++
 | |
| ++	if (!nf_ct_is_confirmed(ct))
 | |
| ++		return XT_CONTINUE;
 | |
| ++
 | |
| ++	devs[dir] = xt_out(par);
 | |
| ++	devs[!dir] = xt_in(par);
 | |
| ++
 | |
| ++	if (!devs[dir] || !devs[!dir])
 | |
| ++		return XT_CONTINUE;
 | |
| ++
 | |
| ++	if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
 | |
| ++		return XT_CONTINUE;
 | |
| ++
 | |
| ++	dir = CTINFO2DIR(ctinfo);
 | |
| ++
 | |
| ++	if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0)
 | |
| ++		goto err_flow_route;
 | |
| ++
 | |
| ++	flow = flow_offload_alloc(ct);
 | |
| ++	if (!flow)
 | |
| ++		goto err_flow_alloc;
 | |
| ++
 | |
| ++	if (flow_offload_route_init(flow, &route) < 0)
 | |
| ++		goto err_flow_add;
 | |
| ++
 | |
| ++	if (tcph) {
 | |
| ++		ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
 | |
| ++		ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
 | |
| ++	}
 | |
| ++
 | |
| ++	table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)];
 | |
| ++	if (flow_offload_add(&table->ft, flow) < 0)
 | |
| ++		goto err_flow_add;
 | |
| ++
 | |
| ++	xt_flowoffload_check_device(table, devs[0]);
 | |
| ++	xt_flowoffload_check_device(table, devs[1]);
 | |
| ++
 | |
| ++	net = read_pnet(&table->ft.net);
 | |
| ++	if (!net)
 | |
| ++		write_pnet(&table->ft.net, xt_net(par));
 | |
| ++
 | |
| ++	dst_release(route.tuple[dir].dst);
 | |
| ++	dst_release(route.tuple[!dir].dst);
 | |
| ++
 | |
| ++	return XT_CONTINUE;
 | |
| ++
 | |
| ++err_flow_add:
 | |
| ++	flow_offload_free(flow);
 | |
| ++err_flow_alloc:
 | |
| ++	dst_release(route.tuple[dir].dst);
 | |
| ++	dst_release(route.tuple[!dir].dst);
 | |
| ++err_flow_route:
 | |
| ++	clear_bit(IPS_OFFLOAD_BIT, &ct->status);
 | |
| ++
 | |
| ++	return XT_CONTINUE;
 | |
| ++}
 | |
| ++
 | |
| ++static int flowoffload_chk(const struct xt_tgchk_param *par)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_target_info *info = par->targinfo;
 | |
| ++
 | |
| ++	if (info->flags & ~XT_FLOWOFFLOAD_MASK)
 | |
| ++		return -EINVAL;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static struct xt_target offload_tg_reg __read_mostly = {
 | |
| ++	.family		= NFPROTO_UNSPEC,
 | |
| ++	.name		= "FLOWOFFLOAD",
 | |
| ++	.revision	= 0,
 | |
| ++	.targetsize	= sizeof(struct xt_flowoffload_target_info),
 | |
| ++	.usersize	= sizeof(struct xt_flowoffload_target_info),
 | |
| ++	.checkentry	= flowoffload_chk,
 | |
| ++	.target		= flowoffload_tg,
 | |
| ++	.me		= THIS_MODULE,
 | |
| ++};
 | |
| ++
 | |
| ++static int flow_offload_netdev_event(struct notifier_block *this,
 | |
| ++				     unsigned long event, void *ptr)
 | |
| ++{
 | |
| ++	struct xt_flowoffload_hook *hook0, *hook1;
 | |
| ++	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 | |
| ++
 | |
| ++	if (event != NETDEV_UNREGISTER)
 | |
| ++		return NOTIFY_DONE;
 | |
| ++
 | |
| ++	spin_lock_bh(&hooks_lock);
 | |
| ++	hook0 = flow_offload_lookup_hook(&flowtable[0], dev);
 | |
| ++	if (hook0)
 | |
| ++		hlist_del(&hook0->list);
 | |
| ++
 | |
| ++	hook1 = flow_offload_lookup_hook(&flowtable[1], dev);
 | |
| ++	if (hook1)
 | |
| ++		hlist_del(&hook1->list);
 | |
| ++	spin_unlock_bh(&hooks_lock);
 | |
| ++
 | |
| ++	if (hook0) {
 | |
| ++		nf_unregister_net_hook(hook0->net, &hook0->ops);
 | |
| ++		kfree(hook0);
 | |
| ++	}
 | |
| ++
 | |
| ++	if (hook1) {
 | |
| ++		nf_unregister_net_hook(hook1->net, &hook1->ops);
 | |
| ++		kfree(hook1);
 | |
| ++	}
 | |
| ++
 | |
| ++	nf_flow_table_cleanup(dev);
 | |
| ++
 | |
| ++	return NOTIFY_DONE;
 | |
| ++}
 | |
| ++
 | |
| ++static struct notifier_block flow_offload_netdev_notifier = {
 | |
| ++	.notifier_call	= flow_offload_netdev_event,
 | |
| ++};
 | |
| ++
 | |
| ++static unsigned int
 | |
| ++nf_flow_offload_inet_hook(void *priv, struct sk_buff *skb,
 | |
| ++			  const struct nf_hook_state *state)
 | |
| ++{
 | |
| ++	switch (skb->protocol) {
 | |
| ++	case htons(ETH_P_IP):
 | |
| ++		return nf_flow_offload_ip_hook(priv, skb, state);
 | |
| ++	case htons(ETH_P_IPV6):
 | |
| ++		return nf_flow_offload_ipv6_hook(priv, skb, state);
 | |
| ++	}
 | |
| ++
 | |
| ++	return NF_ACCEPT;
 | |
| ++}
 | |
| ++
 | |
| ++static int nf_flow_rule_route_inet(struct net *net,
 | |
| ++				   const struct flow_offload *flow,
 | |
| ++				   enum flow_offload_tuple_dir dir,
 | |
| ++				   struct nf_flow_rule *flow_rule)
 | |
| ++{
 | |
| ++	const struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
 | |
| ++	int err;
 | |
| ++
 | |
| ++	switch (flow_tuple->l3proto) {
 | |
| ++	case NFPROTO_IPV4:
 | |
| ++		err = nf_flow_rule_route_ipv4(net, flow, dir, flow_rule);
 | |
| ++		break;
 | |
| ++	case NFPROTO_IPV6:
 | |
| ++		err = nf_flow_rule_route_ipv6(net, flow, dir, flow_rule);
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		err = -1;
 | |
| ++		break;
 | |
| ++	}
 | |
| ++
 | |
| ++	return err;
 | |
| ++}
 | |
| ++
 | |
| ++static struct nf_flowtable_type flowtable_inet = {
 | |
| ++	.family		= NFPROTO_INET,
 | |
| ++	.init		= nf_flow_table_init,
 | |
| ++	.setup		= nf_flow_table_offload_setup,
 | |
| ++	.action		= nf_flow_rule_route_inet,
 | |
| ++	.free		= nf_flow_table_free,
 | |
| ++	.hook		= nf_flow_offload_inet_hook,
 | |
| ++	.owner		= THIS_MODULE,
 | |
| ++};
 | |
| ++
 | |
| ++static int init_flowtable(struct xt_flowoffload_table *tbl)
 | |
| ++{
 | |
| ++	INIT_DELAYED_WORK(&tbl->work, xt_flowoffload_hook_work);
 | |
| ++	tbl->ft.type = &flowtable_inet;
 | |
| ++
 | |
| ++	return nf_flow_table_init(&tbl->ft);
 | |
| ++}
 | |
| ++
 | |
| ++static int __init xt_flowoffload_tg_init(void)
 | |
| ++{
 | |
| ++	int ret;
 | |
| ++
 | |
| ++	register_netdevice_notifier(&flow_offload_netdev_notifier);
 | |
| ++
 | |
| ++	ret = init_flowtable(&flowtable[0]);
 | |
| ++	if (ret)
 | |
| ++		return ret;
 | |
| ++
 | |
| ++	ret = init_flowtable(&flowtable[1]);
 | |
| ++	if (ret)
 | |
| ++		goto cleanup;
 | |
| ++
 | |
| ++	flowtable[1].ft.flags = NF_FLOWTABLE_HW_OFFLOAD;
 | |
| ++
 | |
| ++	ret = xt_register_target(&offload_tg_reg);
 | |
| ++	if (ret)
 | |
| ++		goto cleanup2;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++
 | |
| ++cleanup2:
 | |
| ++	nf_flow_table_free(&flowtable[1].ft);
 | |
| ++cleanup:
 | |
| ++	nf_flow_table_free(&flowtable[0].ft);
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static void __exit xt_flowoffload_tg_exit(void)
 | |
| ++{
 | |
| ++	xt_unregister_target(&offload_tg_reg);
 | |
| ++	unregister_netdevice_notifier(&flow_offload_netdev_notifier);
 | |
| ++	nf_flow_table_free(&flowtable[0].ft);
 | |
| ++	nf_flow_table_free(&flowtable[1].ft);
 | |
| ++}
 | |
| ++
 | |
| ++MODULE_LICENSE("GPL");
 | |
| ++module_init(xt_flowoffload_tg_init);
 | |
| ++module_exit(xt_flowoffload_tg_exit);
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -7,7 +7,6 @@
 | |
| + #include <linux/netdevice.h>
 | |
| + #include <net/ip.h>
 | |
| + #include <net/ip6_route.h>
 | |
| +-#include <net/netfilter/nf_tables.h>
 | |
| + #include <net/netfilter/nf_flow_table.h>
 | |
| + #include <net/netfilter/nf_conntrack.h>
 | |
| + #include <net/netfilter/nf_conntrack_core.h>
 | |
| +@@ -356,8 +355,7 @@ flow_offload_lookup(struct nf_flowtable
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(flow_offload_lookup);
 | |
| + 
 | |
| +-static int
 | |
| +-nf_flow_table_iterate(struct nf_flowtable *flow_table,
 | |
| ++int nf_flow_table_iterate(struct nf_flowtable *flow_table,
 | |
| + 		      void (*iter)(struct flow_offload *flow, void *data),
 | |
| + 		      void *data)
 | |
| + {
 | |
| +@@ -389,6 +387,7 @@ nf_flow_table_iterate(struct nf_flowtabl
 | |
| + 
 | |
| + 	return err;
 | |
| + }
 | |
| ++EXPORT_SYMBOL_GPL(nf_flow_table_iterate);
 | |
| + 
 | |
| + static void nf_flow_offload_gc_step(struct flow_offload *flow, void *data)
 | |
| + {
 | |
| +--- /dev/null
 | |
| ++++ b/include/uapi/linux/netfilter/xt_FLOWOFFLOAD.h
 | |
| +@@ -0,0 +1,17 @@
 | |
| ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 | |
| ++#ifndef _XT_FLOWOFFLOAD_H
 | |
| ++#define _XT_FLOWOFFLOAD_H
 | |
| ++
 | |
| ++#include <linux/types.h>
 | |
| ++
 | |
| ++enum {
 | |
| ++	XT_FLOWOFFLOAD_HW	= 1 << 0,
 | |
| ++
 | |
| ++	XT_FLOWOFFLOAD_MASK	= XT_FLOWOFFLOAD_HW
 | |
| ++};
 | |
| ++
 | |
| ++struct xt_flowoffload_target_info {
 | |
| ++	__u32 flags;
 | |
| ++};
 | |
| ++
 | |
| ++#endif /* _XT_FLOWOFFLOAD_H */
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -266,6 +266,10 @@ void nf_flow_table_free(struct nf_flowta
 | |
| + 
 | |
| + void flow_offload_teardown(struct flow_offload *flow);
 | |
| + 
 | |
| ++int nf_flow_table_iterate(struct nf_flowtable *flow_table,
 | |
| ++                      void (*iter)(struct flow_offload *flow, void *data),
 | |
| ++                      void *data);
 | |
| ++
 | |
| + int nf_flow_snat_port(const struct flow_offload *flow,
 | |
| + 		      struct sk_buff *skb, unsigned int thoff,
 | |
| + 		      u8 protocol, enum flow_offload_tuple_dir dir);
 | |
| diff --git a/target/linux/generic/hack-5.10/651-wireless_mesh_header.patch b/target/linux/generic/hack-5.10/651-wireless_mesh_header.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0639ad4e48
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/651-wireless_mesh_header.patch
 | |
| @@ -0,0 +1,24 @@
 | |
| +From 6d3bc769657b0ee7c7506dad9911111c4226a7ea Mon Sep 17 00:00:00 2001
 | |
| +From: Imre Kaloz <kaloz@openwrt.org>
 | |
| +Date: Fri, 7 Jul 2017 17:21:05 +0200
 | |
| +Subject: mac80211: increase wireless mesh header size
 | |
| +
 | |
| +lede-commit 3d4466cfd8f75f717efdb1f96fdde3c70d865fc1
 | |
| +Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
 | |
| +---
 | |
| + include/linux/netdevice.h | 4 ++--
 | |
| + 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -144,8 +144,8 @@ static inline bool dev_xmit_complete(int
 | |
| + 
 | |
| + #if defined(CONFIG_HYPERV_NET)
 | |
| + # define LL_MAX_HEADER 128
 | |
| +-#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
 | |
| +-# if defined(CONFIG_MAC80211_MESH)
 | |
| ++#elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25) || 1
 | |
| ++# if defined(CONFIG_MAC80211_MESH) || 1
 | |
| + #  define LL_MAX_HEADER 128
 | |
| + # else
 | |
| + #  define LL_MAX_HEADER 96
 | |
| diff --git a/target/linux/generic/hack-5.10/660-fq_codel_defaults.patch b/target/linux/generic/hack-5.10/660-fq_codel_defaults.patch
 | |
| new file mode 100644
 | |
| index 0000000000..6794349e26
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/660-fq_codel_defaults.patch
 | |
| @@ -0,0 +1,27 @@
 | |
| +From a6ccb238939b25851474a279b20367fd24a0e816 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:21:53 +0200
 | |
| +Subject:  hack: net: fq_codel: tune defaults for small devices
 | |
| +
 | |
| +Assume that x86_64 devices always have a big memory and do not need this 
 | |
| +optimization compared to devices with only 32 MB or 64 MB RAM.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + net/sched/sch_fq_codel.c | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/net/sched/sch_fq_codel.c
 | |
| ++++ b/net/sched/sch_fq_codel.c
 | |
| +@@ -461,7 +461,11 @@ static int fq_codel_init(struct Qdisc *s
 | |
| + 
 | |
| + 	sch->limit = 10*1024;
 | |
| + 	q->flows_cnt = 1024;
 | |
| ++#ifdef CONFIG_X86_64
 | |
| + 	q->memory_limit = 32 << 20; /* 32 MBytes */
 | |
| ++#else
 | |
| ++	q->memory_limit = 4 << 20; /* 4 MBytes */
 | |
| ++#endif
 | |
| + 	q->drop_batch_size = 64;
 | |
| + 	q->quantum = psched_mtu(qdisc_dev(sch));
 | |
| + 	INIT_LIST_HEAD(&q->new_flows);
 | |
| diff --git a/target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch b/target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch
 | |
| new file mode 100644
 | |
| index 0000000000..ceabf81249
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/661-use_fq_codel_by_default.patch
 | |
| @@ -0,0 +1,100 @@
 | |
| +From 1d418f7e88035ed7a94073f6354246c66e9193e9 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:22:58 +0200
 | |
| +Subject: fq_codel: switch default qdisc from pfifo_fast to fq_codel and remove pfifo_fast
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/net/sch_generic.h | 3 ++-
 | |
| + net/sched/Kconfig         | 3 ++-
 | |
| + net/sched/sch_api.c       | 2 +-
 | |
| + net/sched/sch_fq_codel.c  | 3 ++-
 | |
| + net/sched/sch_generic.c   | 4 ++--
 | |
| + 5 files changed, 9 insertions(+), 6 deletions(-)
 | |
| +
 | |
| +--- a/include/net/sch_generic.h
 | |
| ++++ b/include/net/sch_generic.h
 | |
| +@@ -578,12 +578,13 @@ extern struct Qdisc_ops noop_qdisc_ops;
 | |
| + extern struct Qdisc_ops pfifo_fast_ops;
 | |
| + extern struct Qdisc_ops mq_qdisc_ops;
 | |
| + extern struct Qdisc_ops noqueue_qdisc_ops;
 | |
| ++extern struct Qdisc_ops fq_codel_qdisc_ops;
 | |
| + extern const struct Qdisc_ops *default_qdisc_ops;
 | |
| + static inline const struct Qdisc_ops *
 | |
| + get_default_qdisc_ops(const struct net_device *dev, int ntx)
 | |
| + {
 | |
| + 	return ntx < dev->real_num_tx_queues ?
 | |
| +-			default_qdisc_ops : &pfifo_fast_ops;
 | |
| ++			default_qdisc_ops : &fq_codel_qdisc_ops;
 | |
| + }
 | |
| + 
 | |
| + struct Qdisc_class_common {
 | |
| +--- a/net/sched/Kconfig
 | |
| ++++ b/net/sched/Kconfig
 | |
| +@@ -4,8 +4,9 @@
 | |
| + #
 | |
| + 
 | |
| + menuconfig NET_SCHED
 | |
| +-	bool "QoS and/or fair queueing"
 | |
| ++	def_bool y
 | |
| + 	select NET_SCH_FIFO
 | |
| ++	select NET_SCH_FQ_CODEL
 | |
| + 	help
 | |
| + 	  When the kernel has several packets to send out over a network
 | |
| + 	  device, it has to decide which ones to send first, which ones to
 | |
| +--- a/net/sched/sch_api.c
 | |
| ++++ b/net/sched/sch_api.c
 | |
| +@@ -2282,7 +2282,7 @@ static int __init pktsched_init(void)
 | |
| + 		return err;
 | |
| + 	}
 | |
| + 
 | |
| +-	register_qdisc(&pfifo_fast_ops);
 | |
| ++	register_qdisc(&fq_codel_qdisc_ops);
 | |
| + 	register_qdisc(&pfifo_qdisc_ops);
 | |
| + 	register_qdisc(&bfifo_qdisc_ops);
 | |
| + 	register_qdisc(&pfifo_head_drop_qdisc_ops);
 | |
| +--- a/net/sched/sch_fq_codel.c
 | |
| ++++ b/net/sched/sch_fq_codel.c
 | |
| +@@ -701,7 +701,7 @@ static const struct Qdisc_class_ops fq_c
 | |
| + 	.walk		=	fq_codel_walk,
 | |
| + };
 | |
| + 
 | |
| +-static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = {
 | |
| ++struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = {
 | |
| + 	.cl_ops		=	&fq_codel_class_ops,
 | |
| + 	.id		=	"fq_codel",
 | |
| + 	.priv_size	=	sizeof(struct fq_codel_sched_data),
 | |
| +@@ -716,6 +716,7 @@ static struct Qdisc_ops fq_codel_qdisc_o
 | |
| + 	.dump_stats =	fq_codel_dump_stats,
 | |
| + 	.owner		=	THIS_MODULE,
 | |
| + };
 | |
| ++EXPORT_SYMBOL(fq_codel_qdisc_ops);
 | |
| + 
 | |
| + static int __init fq_codel_module_init(void)
 | |
| + {
 | |
| +--- a/net/sched/sch_generic.c
 | |
| ++++ b/net/sched/sch_generic.c
 | |
| +@@ -32,7 +32,7 @@
 | |
| + #include <net/xfrm.h>
 | |
| + 
 | |
| + /* Qdisc to use by default */
 | |
| +-const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops;
 | |
| ++const struct Qdisc_ops *default_qdisc_ops = &fq_codel_qdisc_ops;
 | |
| + EXPORT_SYMBOL(default_qdisc_ops);
 | |
| + 
 | |
| + /* Main transmission queue. */
 | |
| +@@ -1018,12 +1018,12 @@ static void attach_one_default_qdisc(str
 | |
| + 				     void *_unused)
 | |
| + {
 | |
| + 	struct Qdisc *qdisc;
 | |
| +-	const struct Qdisc_ops *ops = default_qdisc_ops;
 | |
| ++	const struct Qdisc_ops *ops = &fq_codel_qdisc_ops;
 | |
| + 
 | |
| + 	if (dev->priv_flags & IFF_NO_QUEUE)
 | |
| + 		ops = &noqueue_qdisc_ops;
 | |
| + 	else if(dev->type == ARPHRD_CAN)
 | |
| +-		ops = &pfifo_fast_ops;
 | |
| ++		ops = &fq_codel_qdisc_ops;
 | |
| + 
 | |
| + 	qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL);
 | |
| + 	if (!qdisc)
 | |
| diff --git a/target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch b/target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch
 | |
| new file mode 100644
 | |
| index 0000000000..560937a7c1
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/700-swconfig_switch_drivers.patch
 | |
| @@ -0,0 +1,129 @@
 | |
| +From 36e516290611e613aa92996cb4339561452695b4 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 7 Jul 2017 17:24:23 +0200
 | |
| +Subject: net: swconfig: adds openwrt switch layer
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/net/phy/Kconfig   | 83 +++++++++++++++++++++++++++++++++++++++++++++++
 | |
| + drivers/net/phy/Makefile  | 15 +++++++++
 | |
| + include/uapi/linux/Kbuild |  1 +
 | |
| + 3 files changed, 99 insertions(+)
 | |
| +
 | |
| +--- a/drivers/net/phy/Kconfig
 | |
| ++++ b/drivers/net/phy/Kconfig
 | |
| +@@ -61,6 +61,80 @@ config SFP
 | |
| + 	depends on HWMON || HWMON=n
 | |
| + 	select MDIO_I2C
 | |
| + 
 | |
| ++comment "Switch configuration API + drivers"
 | |
| ++
 | |
| ++config SWCONFIG
 | |
| ++	tristate "Switch configuration API"
 | |
| ++	help
 | |
| ++	  Switch configuration API using netlink. This allows
 | |
| ++	  you to configure the VLAN features of certain switches.
 | |
| ++
 | |
| ++config SWCONFIG_LEDS
 | |
| ++	bool "Switch LED trigger support"
 | |
| ++	depends on (SWCONFIG && LEDS_TRIGGERS)
 | |
| ++
 | |
| ++config ADM6996_PHY
 | |
| ++	tristate "Driver for ADM6996 switches"
 | |
| ++	select SWCONFIG
 | |
| ++	help
 | |
| ++	  Currently supports the ADM6996FC and ADM6996M switches.
 | |
| ++	  Support for FC is very limited.
 | |
| ++
 | |
| ++config AR8216_PHY
 | |
| ++	tristate "Driver for Atheros AR8216 switches"
 | |
| ++	select SWCONFIG
 | |
| ++
 | |
| ++config AR8216_PHY_LEDS
 | |
| ++	bool "Atheros AR8216 switch LED support"
 | |
| ++	depends on (AR8216_PHY && LEDS_CLASS)
 | |
| ++
 | |
| ++source "drivers/net/phy/b53/Kconfig"
 | |
| ++
 | |
| ++config IP17XX_PHY
 | |
| ++	tristate "Driver for IC+ IP17xx switches"
 | |
| ++	select SWCONFIG
 | |
| ++
 | |
| ++config PSB6970_PHY
 | |
| ++	tristate "Lantiq XWAY Tantos (PSB6970) Ethernet switch"
 | |
| ++	select SWCONFIG
 | |
| ++	select ETHERNET_PACKET_MANGLE
 | |
| ++
 | |
| ++config RTL8306_PHY
 | |
| ++	tristate "Driver for Realtek RTL8306S switches"
 | |
| ++	select SWCONFIG
 | |
| ++
 | |
| ++config RTL8366_SMI
 | |
| ++	tristate "Driver for the RTL8366 SMI interface"
 | |
| ++	depends on GPIOLIB
 | |
| ++	help
 | |
| ++	  This module implements the SMI interface protocol which is used
 | |
| ++	  by some RTL8366 ethernet switch devices via the generic GPIO API.
 | |
| ++
 | |
| ++if RTL8366_SMI
 | |
| ++
 | |
| ++config RTL8366_SMI_DEBUG_FS
 | |
| ++	bool "RTL8366 SMI interface debugfs support"
 | |
| ++        depends on DEBUG_FS
 | |
| ++        default n
 | |
| ++
 | |
| ++config RTL8366S_PHY
 | |
| ++	tristate "Driver for the Realtek RTL8366S switch"
 | |
| ++	select SWCONFIG
 | |
| ++
 | |
| ++config RTL8366RB_PHY
 | |
| ++	tristate "Driver for the Realtek RTL8366RB switch"
 | |
| ++	select SWCONFIG
 | |
| ++
 | |
| ++config RTL8367_PHY
 | |
| ++	tristate "Driver for the Realtek RTL8367R/M switches"
 | |
| ++	select SWCONFIG
 | |
| ++
 | |
| ++config RTL8367B_PHY
 | |
| ++	tristate "Driver fot the Realtek RTL8367R-VB switch"
 | |
| ++	select SWCONFIG
 | |
| ++
 | |
| ++endif # RTL8366_SMI
 | |
| ++
 | |
| + comment "MII PHY device drivers"
 | |
| + 
 | |
| + config AMD_PHY
 | |
| +--- a/drivers/net/phy/Makefile
 | |
| ++++ b/drivers/net/phy/Makefile
 | |
| +@@ -24,6 +24,19 @@ libphy-$(CONFIG_LED_TRIGGER_PHY)	+= phy_
 | |
| + obj-$(CONFIG_PHYLINK)		+= phylink.o
 | |
| + obj-$(CONFIG_PHYLIB)		+= libphy.o
 | |
| + 
 | |
| ++obj-$(CONFIG_SWCONFIG)		+= swconfig.o
 | |
| ++obj-$(CONFIG_ADM6996_PHY)	+= adm6996.o
 | |
| ++obj-$(CONFIG_AR8216_PHY)	+= ar8216.o ar8327.o
 | |
| ++obj-$(CONFIG_SWCONFIG_B53)	+= b53/
 | |
| ++obj-$(CONFIG_IP17XX_PHY)	+= ip17xx.o
 | |
| ++obj-$(CONFIG_PSB6970_PHY)	+= psb6970.o
 | |
| ++obj-$(CONFIG_RTL8306_PHY)	+= rtl8306.o
 | |
| ++obj-$(CONFIG_RTL8366_SMI)	+= rtl8366_smi.o
 | |
| ++obj-$(CONFIG_RTL8366S_PHY)	+= rtl8366s.o
 | |
| ++obj-$(CONFIG_RTL8366RB_PHY)	+= rtl8366rb.o
 | |
| ++obj-$(CONFIG_RTL8367_PHY)	+= rtl8367.o
 | |
| ++obj-$(CONFIG_RTL8367B_PHY)	+= rtl8367b.o
 | |
| ++
 | |
| + obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o
 | |
| + 
 | |
| + obj-$(CONFIG_SFP)		+= sfp.o
 | |
| +--- a/include/linux/platform_data/b53.h
 | |
| ++++ b/include/linux/platform_data/b53.h
 | |
| +@@ -29,6 +29,9 @@ struct b53_platform_data {
 | |
| + 	u32 chip_id;
 | |
| + 	u16 enabled_ports;
 | |
| + 
 | |
| ++	/* allow to specify an ethX alias */
 | |
| ++	const char *alias;
 | |
| ++
 | |
| + 	/* only used by MMAP'd driver */
 | |
| + 	unsigned big_endian:1;
 | |
| + 	void __iomem *regs;
 | |
| diff --git a/target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch b/target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch
 | |
| new file mode 100644
 | |
| index 0000000000..f301cc1e2d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/710-net-dsa-mv88e6xxx-default-VID-1.patch
 | |
| @@ -0,0 +1,18 @@
 | |
| +--- a/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| ++++ b/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| +@@ -2088,6 +2088,7 @@ static int mv88e6xxx_port_fdb_add(struct
 | |
| + 	struct mv88e6xxx_chip *chip = ds->priv;
 | |
| + 	int err;
 | |
| + 
 | |
| ++	vid = vid ? : 1;
 | |
| + 	mv88e6xxx_reg_lock(chip);
 | |
| + 	err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid,
 | |
| + 					   MV88E6XXX_G1_ATU_DATA_STATE_UC_STATIC);
 | |
| +@@ -2102,6 +2103,7 @@ static int mv88e6xxx_port_fdb_del(struct
 | |
| + 	struct mv88e6xxx_chip *chip = ds->priv;
 | |
| + 	int err;
 | |
| + 
 | |
| ++	vid = vid ? : 1;
 | |
| + 	mv88e6xxx_reg_lock(chip);
 | |
| + 	err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, 0);
 | |
| + 	mv88e6xxx_reg_unlock(chip);
 | |
| diff --git a/target/linux/generic/hack-5.10/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch b/target/linux/generic/hack-5.10/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch
 | |
| new file mode 100644
 | |
| index 0000000000..46a1ba1d96
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/711-net-dsa-mv88e6xxx-disable-ATU-violation.patch
 | |
| @@ -0,0 +1,12 @@
 | |
| +--- a/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| ++++ b/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| +@@ -2650,6 +2650,9 @@ static int mv88e6xxx_setup_port(struct m
 | |
| + 	if (dsa_is_cpu_port(ds, port))
 | |
| + 		reg = 0;
 | |
| + 
 | |
| ++	/* Disable ATU member violation interrupt */
 | |
| ++	reg |= MV88E6XXX_PORT_ASSOC_VECTOR_IGNORE_WRONG;
 | |
| ++
 | |
| + 	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR,
 | |
| + 				   reg);
 | |
| + 	if (err)
 | |
| diff --git a/target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch b/target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1c1b727ab7
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/773-bgmac-add-srab-switch.patch
 | |
| @@ -0,0 +1,98 @@
 | |
| +From 3cb240533ab787899dc7f17aa7d6c5b4810e2e58 Mon Sep 17 00:00:00 2001
 | |
| +From: Hauke Mehrtens <hauke@hauke-m.de>
 | |
| +Date: Fri, 7 Jul 2017 17:26:01 +0200
 | |
| +Subject: bcm53xx: bgmac: use srab switch driver
 | |
| +
 | |
| +use the srab switch driver on these SoCs.
 | |
| +
 | |
| +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | |
| +---
 | |
| + drivers/net/ethernet/broadcom/bgmac-bcma.c |  1 +
 | |
| + drivers/net/ethernet/broadcom/bgmac.c      | 24 ++++++++++++++++++++++++
 | |
| + drivers/net/ethernet/broadcom/bgmac.h      |  4 ++++
 | |
| + 3 files changed, 29 insertions(+)
 | |
| +
 | |
| +--- a/drivers/net/ethernet/broadcom/bgmac-bcma.c
 | |
| ++++ b/drivers/net/ethernet/broadcom/bgmac-bcma.c
 | |
| +@@ -268,6 +268,7 @@ static int bgmac_probe(struct bcma_devic
 | |
| + 		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
 | |
| + 		bgmac->feature_flags |= BGMAC_FEAT_NO_RESET;
 | |
| + 		bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500;
 | |
| ++		bgmac->feature_flags |= BGMAC_FEAT_SRAB;
 | |
| + 		break;
 | |
| + 	default:
 | |
| + 		bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST;
 | |
| +--- a/drivers/net/ethernet/broadcom/bgmac.c
 | |
| ++++ b/drivers/net/ethernet/broadcom/bgmac.c
 | |
| +@@ -12,6 +12,7 @@
 | |
| + #include <linux/bcma/bcma.h>
 | |
| + #include <linux/etherdevice.h>
 | |
| + #include <linux/interrupt.h>
 | |
| ++#include <linux/platform_data/b53.h>
 | |
| + #include <linux/bcm47xx_nvram.h>
 | |
| + #include <linux/phy.h>
 | |
| + #include <linux/phy_fixed.h>
 | |
| +@@ -1408,6 +1409,17 @@ static const struct ethtool_ops bgmac_et
 | |
| + 	.set_link_ksettings     = phy_ethtool_set_link_ksettings,
 | |
| + };
 | |
| + 
 | |
| ++static struct b53_platform_data bgmac_b53_pdata = {
 | |
| ++};
 | |
| ++
 | |
| ++static struct platform_device bgmac_b53_dev = {
 | |
| ++	.name		= "b53-srab-switch",
 | |
| ++	.id		= -1,
 | |
| ++	.dev		= {
 | |
| ++		.platform_data = &bgmac_b53_pdata,
 | |
| ++	},
 | |
| ++};
 | |
| ++
 | |
| + /**************************************************
 | |
| +  * MII
 | |
| +  **************************************************/
 | |
| +@@ -1542,6 +1554,14 @@ 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;
 | |
| + 
 | |
| ++	if ((bgmac->feature_flags & BGMAC_FEAT_SRAB) && !bgmac_b53_pdata.regs) {
 | |
| ++		bgmac_b53_pdata.regs = ioremap_nocache(0x18007000, 0x1000);
 | |
| ++
 | |
| ++		err = platform_device_register(&bgmac_b53_dev);
 | |
| ++		if (!err)
 | |
| ++			bgmac->b53_device = &bgmac_b53_dev;
 | |
| ++	}
 | |
| ++
 | |
| + 	err = register_netdev(bgmac->net_dev);
 | |
| + 	if (err) {
 | |
| + 		dev_err(bgmac->dev, "Cannot register net device\n");
 | |
| +@@ -1564,6 +1584,10 @@ EXPORT_SYMBOL_GPL(bgmac_enet_probe);
 | |
| + 
 | |
| + void bgmac_enet_remove(struct bgmac *bgmac)
 | |
| + {
 | |
| ++	if (bgmac->b53_device)
 | |
| ++		platform_device_unregister(&bgmac_b53_dev);
 | |
| ++	bgmac->b53_device = NULL;
 | |
| ++
 | |
| + 	unregister_netdev(bgmac->net_dev);
 | |
| + 	phy_disconnect(bgmac->net_dev->phydev);
 | |
| + 	netif_napi_del(&bgmac->napi);
 | |
| +--- a/drivers/net/ethernet/broadcom/bgmac.h
 | |
| ++++ b/drivers/net/ethernet/broadcom/bgmac.h
 | |
| +@@ -428,6 +428,7 @@
 | |
| + #define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII	BIT(18)
 | |
| + #define BGMAC_FEAT_CC7_IF_TYPE_RGMII	BIT(19)
 | |
| + #define BGMAC_FEAT_IDM_MASK		BIT(20)
 | |
| ++#define BGMAC_FEAT_SRAB			BIT(21)
 | |
| + 
 | |
| + struct bgmac_slot_info {
 | |
| + 	union {
 | |
| +@@ -533,6 +534,9 @@ struct bgmac {
 | |
| + 	void (*cmn_maskset32)(struct bgmac *bgmac, u16 offset, u32 mask,
 | |
| + 			      u32 set);
 | |
| + 	int (*phy_connect)(struct bgmac *bgmac);
 | |
| ++
 | |
| ++	/* platform device for associated switch */
 | |
| ++	struct platform_device *b53_device;
 | |
| + };
 | |
| + 
 | |
| + struct bgmac *bgmac_alloc(struct device *dev);
 | |
| diff --git a/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch b/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
 | |
| new file mode 100644
 | |
| index 0000000000..fc2a0a4862
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/901-debloat_sock_diag.patch
 | |
| @@ -0,0 +1,162 @@
 | |
| +From 3b6115d6b57a263bdc8c9b1df273bd4a7955eead Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sat, 8 Jul 2017 08:16:31 +0200
 | |
| +Subject: debloat: add some debloat patches, strip down procfs and make O_DIRECT support optional, saves ~15K after lzma on MIPS
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + net/Kconfig         | 3 +++
 | |
| + net/core/Makefile   | 3 ++-
 | |
| + net/core/sock.c     | 2 ++
 | |
| + net/ipv4/Kconfig    | 1 +
 | |
| + net/netlink/Kconfig | 1 +
 | |
| + net/packet/Kconfig  | 1 +
 | |
| + net/unix/Kconfig    | 1 +
 | |
| + 7 files changed, 11 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/net/Kconfig
 | |
| ++++ b/net/Kconfig
 | |
| +@@ -98,6 +98,9 @@ source "net/mptcp/Kconfig"
 | |
| + 
 | |
| + endif # if INET
 | |
| + 
 | |
| ++config SOCK_DIAG
 | |
| ++	bool
 | |
| ++
 | |
| + config NETWORK_SECMARK
 | |
| + 	bool "Security Marking"
 | |
| + 	help
 | |
| +--- a/net/core/Makefile
 | |
| ++++ b/net/core/Makefile
 | |
| +@@ -10,9 +10,10 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_core.
 | |
| + 
 | |
| + obj-y		     += dev.o dev_addr_lists.o dst.o netevent.o \
 | |
| + 			neighbour.o rtnetlink.o utils.o link_watch.o filter.o \
 | |
| +-			sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \
 | |
| ++ 			dev_ioctl.o tso.o sock_reuseport.o \
 | |
| + 			fib_notifier.o xdp.o flow_offload.o
 | |
| + 
 | |
| ++obj-$(CONFIG_SOCK_DIAG) += sock_diag.o
 | |
| + obj-y += net-sysfs.o
 | |
| + obj-$(CONFIG_PAGE_POOL) += page_pool.o
 | |
| + obj-$(CONFIG_PROC_FS) += net-procfs.o
 | |
| +--- a/net/core/sock.c
 | |
| ++++ b/net/core/sock.c
 | |
| +@@ -114,6 +114,7 @@
 | |
| + #include <linux/memcontrol.h>
 | |
| + #include <linux/prefetch.h>
 | |
| + #include <linux/compat.h>
 | |
| ++#include <linux/cookie.h>
 | |
| + 
 | |
| + #include <linux/uaccess.h>
 | |
| + 
 | |
| +@@ -141,6 +142,7 @@
 | |
| + 
 | |
| + static DEFINE_MUTEX(proto_list_mutex);
 | |
| + static LIST_HEAD(proto_list);
 | |
| ++DEFINE_COOKIE(sock_cookie);
 | |
| + 
 | |
| + static void sock_inuse_add(struct net *net, int val);
 | |
| + 
 | |
| +@@ -526,6 +528,18 @@ discard_and_relse:
 | |
| + }
 | |
| + EXPORT_SYMBOL(__sk_receive_skb);
 | |
| + 
 | |
| ++u64 __sock_gen_cookie(struct sock *sk)
 | |
| ++{
 | |
| ++	while (1) {
 | |
| ++		u64 res = atomic64_read(&sk->sk_cookie);
 | |
| ++
 | |
| ++		if (res)
 | |
| ++			return res;
 | |
| ++		res = gen_cookie_next(&sock_cookie);
 | |
| ++		atomic64_cmpxchg(&sk->sk_cookie, 0, res);
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| + struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie)
 | |
| + {
 | |
| + 	struct dst_entry *dst = __sk_dst_get(sk);
 | |
| +@@ -1808,9 +1822,11 @@ static void __sk_free(struct sock *sk)
 | |
| + 	if (likely(sk->sk_net_refcnt))
 | |
| + 		sock_inuse_add(sock_net(sk), -1);
 | |
| + 
 | |
| ++#ifdef CONFIG_SOCK_DIAG
 | |
| + 	if (unlikely(sk->sk_net_refcnt && sock_diag_has_destroy_listeners(sk)))
 | |
| + 		sock_diag_broadcast_destroy(sk);
 | |
| + 	else
 | |
| ++#endif
 | |
| + 		sk_destruct(sk);
 | |
| + }
 | |
| + 
 | |
| +--- a/net/core/sock_diag.c
 | |
| ++++ b/net/core/sock_diag.c
 | |
| +@@ -11,7 +11,6 @@
 | |
| + #include <linux/tcp.h>
 | |
| + #include <linux/workqueue.h>
 | |
| + #include <linux/nospec.h>
 | |
| +-#include <linux/cookie.h>
 | |
| + #include <linux/inet_diag.h>
 | |
| + #include <linux/sock_diag.h>
 | |
| + 
 | |
| +@@ -20,20 +19,6 @@ static int (*inet_rcv_compat)(struct sk_
 | |
| + static DEFINE_MUTEX(sock_diag_table_mutex);
 | |
| + static struct workqueue_struct *broadcast_wq;
 | |
| + 
 | |
| +-DEFINE_COOKIE(sock_cookie);
 | |
| +-
 | |
| +-u64 __sock_gen_cookie(struct sock *sk)
 | |
| +-{
 | |
| +-	while (1) {
 | |
| +-		u64 res = atomic64_read(&sk->sk_cookie);
 | |
| +-
 | |
| +-		if (res)
 | |
| +-			return res;
 | |
| +-		res = gen_cookie_next(&sock_cookie);
 | |
| +-		atomic64_cmpxchg(&sk->sk_cookie, 0, res);
 | |
| +-	}
 | |
| +-}
 | |
| +-
 | |
| + int sock_diag_check_cookie(struct sock *sk, const __u32 *cookie)
 | |
| + {
 | |
| + 	u64 res;
 | |
| +--- a/net/ipv4/Kconfig
 | |
| ++++ b/net/ipv4/Kconfig
 | |
| +@@ -414,6 +414,7 @@ config INET_TUNNEL
 | |
| + 
 | |
| + config INET_DIAG
 | |
| + 	tristate "INET: socket monitoring interface"
 | |
| ++	select SOCK_DIAG
 | |
| + 	default y
 | |
| + 	help
 | |
| + 	  Support for INET (TCP, DCCP, etc) socket monitoring interface used by
 | |
| +--- a/net/netlink/Kconfig
 | |
| ++++ b/net/netlink/Kconfig
 | |
| +@@ -5,6 +5,7 @@
 | |
| + 
 | |
| + config NETLINK_DIAG
 | |
| + 	tristate "NETLINK: socket monitoring interface"
 | |
| ++	select SOCK_DIAG
 | |
| + 	default n
 | |
| + 	help
 | |
| + 	  Support for NETLINK socket monitoring interface used by the ss tool.
 | |
| +--- a/net/packet/Kconfig
 | |
| ++++ b/net/packet/Kconfig
 | |
| +@@ -19,6 +19,7 @@ config PACKET
 | |
| + config PACKET_DIAG
 | |
| + 	tristate "Packet: sockets monitoring interface"
 | |
| + 	depends on PACKET
 | |
| ++	select SOCK_DIAG
 | |
| + 	default n
 | |
| + 	help
 | |
| + 	  Support for PF_PACKET sockets monitoring interface used by the ss tool.
 | |
| +--- a/net/unix/Kconfig
 | |
| ++++ b/net/unix/Kconfig
 | |
| +@@ -28,6 +28,7 @@ config UNIX_SCM
 | |
| + config UNIX_DIAG
 | |
| + 	tristate "UNIX: socket monitoring interface"
 | |
| + 	depends on UNIX
 | |
| ++	select SOCK_DIAG
 | |
| + 	default n
 | |
| + 	help
 | |
| + 	  Support for UNIX socket monitoring interface used by the ss tool.
 | |
| diff --git a/target/linux/generic/hack-5.10/902-debloat_proc.patch b/target/linux/generic/hack-5.10/902-debloat_proc.patch
 | |
| new file mode 100644
 | |
| index 0000000000..3208e5554f
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/902-debloat_proc.patch
 | |
| @@ -0,0 +1,408 @@
 | |
| +From 9e3f1d0805b2d919904dd9a4ff0d956314cc3cba Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sat, 8 Jul 2017 08:20:09 +0200
 | |
| +Subject: debloat: procfs
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + fs/locks.c               |  2 ++
 | |
| + fs/proc/Kconfig          |  5 +++++
 | |
| + fs/proc/consoles.c       |  3 +++
 | |
| + fs/proc/proc_tty.c       | 11 ++++++++++-
 | |
| + include/net/snmp.h       | 18 +++++++++++++++++-
 | |
| + ipc/msg.c                |  3 +++
 | |
| + ipc/sem.c                |  2 ++
 | |
| + ipc/shm.c                |  2 ++
 | |
| + ipc/util.c               |  3 +++
 | |
| + kernel/exec_domain.c     |  2 ++
 | |
| + kernel/irq/proc.c        |  9 +++++++++
 | |
| + kernel/time/timer_list.c |  2 ++
 | |
| + mm/vmalloc.c             |  2 ++
 | |
| + mm/vmstat.c              |  8 +++++---
 | |
| + net/8021q/vlanproc.c     |  6 ++++++
 | |
| + net/core/net-procfs.c    | 18 ++++++++++++------
 | |
| + net/core/sock.c          |  2 ++
 | |
| + net/ipv4/fib_trie.c      | 18 ++++++++++++------
 | |
| + net/ipv4/proc.c          |  3 +++
 | |
| + net/ipv4/route.c         |  3 +++
 | |
| + 20 files changed, 105 insertions(+), 17 deletions(-)
 | |
| +
 | |
| +--- a/fs/locks.c
 | |
| ++++ b/fs/locks.c
 | |
| +@@ -2993,6 +2993,8 @@ static const struct seq_operations locks
 | |
| + 
 | |
| + static int __init proc_locks_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| + 	proc_create_seq_private("locks", 0, NULL, &locks_seq_operations,
 | |
| + 			sizeof(struct locks_iterator), NULL);
 | |
| + 	return 0;
 | |
| +--- a/fs/proc/Kconfig
 | |
| ++++ b/fs/proc/Kconfig
 | |
| +@@ -100,6 +100,11 @@ config PROC_CHILDREN
 | |
| + 	  Say Y if you are running any user-space software which takes benefit from
 | |
| + 	  this interface. For example, rkt is such a piece of software.
 | |
| + 
 | |
| ++config PROC_STRIPPED
 | |
| ++	default n
 | |
| ++	depends on EXPERT
 | |
| ++	bool "Strip non-essential /proc functionality to reduce code size"
 | |
| ++
 | |
| + config PROC_PID_ARCH_STATUS
 | |
| + 	def_bool n
 | |
| + 	depends on PROC_FS
 | |
| +--- a/fs/proc/consoles.c
 | |
| ++++ b/fs/proc/consoles.c
 | |
| +@@ -92,6 +92,9 @@ static const struct seq_operations conso
 | |
| + 
 | |
| + static int __init proc_consoles_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| ++
 | |
| + 	proc_create_seq("consoles", 0, NULL, &consoles_op);
 | |
| + 	return 0;
 | |
| + }
 | |
| +--- a/fs/proc/proc_tty.c
 | |
| ++++ b/fs/proc/proc_tty.c
 | |
| +@@ -133,7 +133,10 @@ static const struct seq_operations tty_d
 | |
| + void proc_tty_register_driver(struct tty_driver *driver)
 | |
| + {
 | |
| + 	struct proc_dir_entry *ent;
 | |
| +-		
 | |
| ++
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| ++
 | |
| + 	if (!driver->driver_name || driver->proc_entry ||
 | |
| + 	    !driver->ops->proc_show)
 | |
| + 		return;
 | |
| +@@ -150,6 +153,9 @@ void proc_tty_unregister_driver(struct t
 | |
| + {
 | |
| + 	struct proc_dir_entry *ent;
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| ++
 | |
| + 	ent = driver->proc_entry;
 | |
| + 	if (!ent)
 | |
| + 		return;
 | |
| +@@ -164,6 +170,9 @@ void proc_tty_unregister_driver(struct t
 | |
| +  */
 | |
| + void __init proc_tty_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| ++
 | |
| + 	if (!proc_mkdir("tty", NULL))
 | |
| + 		return;
 | |
| + 	proc_mkdir("tty/ldisc", NULL);	/* Preserved: it's userspace visible */
 | |
| +--- a/include/net/snmp.h
 | |
| ++++ b/include/net/snmp.h
 | |
| +@@ -124,6 +124,21 @@ struct linux_tls_mib {
 | |
| + #define DECLARE_SNMP_STAT(type, name)	\
 | |
| + 	extern __typeof__(type) __percpu *name
 | |
| + 
 | |
| ++#ifdef CONFIG_PROC_STRIPPED
 | |
| ++#define __SNMP_STATS_DUMMY(mib)	\
 | |
| ++	do { (void) mib->mibs[0]; } while(0)
 | |
| ++
 | |
| ++#define __SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
 | |
| ++#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) __SNMP_STATS_DUMMY(mib)
 | |
| ++#define SNMP_INC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
 | |
| ++#define SNMP_DEC_STATS(mib, field) __SNMP_STATS_DUMMY(mib)
 | |
| ++#define __SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
 | |
| ++#define SNMP_ADD_STATS(mib, field, addend) __SNMP_STATS_DUMMY(mib)
 | |
| ++#define SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
 | |
| ++#define __SNMP_UPD_PO_STATS(mib, basefield, addend) __SNMP_STATS_DUMMY(mib)
 | |
| ++
 | |
| ++#else
 | |
| ++
 | |
| + #define __SNMP_INC_STATS(mib, field)	\
 | |
| + 			__this_cpu_inc(mib->mibs[field])
 | |
| + 
 | |
| +@@ -154,8 +169,9 @@ struct linux_tls_mib {
 | |
| + 		__this_cpu_add(ptr[basefield##OCTETS], addend);	\
 | |
| + 	} while (0)
 | |
| + 
 | |
| ++#endif
 | |
| + 
 | |
| +-#if BITS_PER_LONG==32
 | |
| ++#if (BITS_PER_LONG==32) && !defined(CONFIG_PROC_STRIPPED)
 | |
| + 
 | |
| + #define __SNMP_ADD_STATS64(mib, field, addend) 				\
 | |
| + 	do {								\
 | |
| +--- a/ipc/msg.c
 | |
| ++++ b/ipc/msg.c
 | |
| +@@ -1348,6 +1348,9 @@ void __init msg_init(void)
 | |
| + {
 | |
| + 	msg_init_ns(&init_ipc_ns);
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| ++
 | |
| + 	ipc_init_proc_interface("sysvipc/msg",
 | |
| + 				"       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
 | |
| + 				IPC_MSG_IDS, sysvipc_msg_proc_show);
 | |
| +--- a/ipc/sem.c
 | |
| ++++ b/ipc/sem.c
 | |
| +@@ -266,6 +266,8 @@ void sem_exit_ns(struct ipc_namespace *n
 | |
| + void __init sem_init(void)
 | |
| + {
 | |
| + 	sem_init_ns(&init_ipc_ns);
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| + 	ipc_init_proc_interface("sysvipc/sem",
 | |
| + 				"       key      semid perms      nsems   uid   gid  cuid  cgid      otime      ctime\n",
 | |
| + 				IPC_SEM_IDS, sysvipc_sem_proc_show);
 | |
| +--- a/ipc/shm.c
 | |
| ++++ b/ipc/shm.c
 | |
| +@@ -144,6 +144,8 @@ pure_initcall(ipc_ns_init);
 | |
| + 
 | |
| + void __init shm_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| + 	ipc_init_proc_interface("sysvipc/shm",
 | |
| + #if BITS_PER_LONG <= 32
 | |
| + 				"       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime        rss       swap\n",
 | |
| +--- a/ipc/util.c
 | |
| ++++ b/ipc/util.c
 | |
| +@@ -140,6 +140,9 @@ void __init ipc_init_proc_interface(cons
 | |
| + 	struct proc_dir_entry *pde;
 | |
| + 	struct ipc_proc_iface *iface;
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| ++
 | |
| + 	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
 | |
| + 	if (!iface)
 | |
| + 		return;
 | |
| +--- a/kernel/exec_domain.c
 | |
| ++++ b/kernel/exec_domain.c
 | |
| +@@ -29,6 +29,8 @@ static int execdomains_proc_show(struct
 | |
| + 
 | |
| + static int __init proc_execdomains_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| + 	proc_create_single("execdomains", 0, NULL, execdomains_proc_show);
 | |
| + 	return 0;
 | |
| + }
 | |
| +--- a/kernel/irq/proc.c
 | |
| ++++ b/kernel/irq/proc.c
 | |
| +@@ -341,6 +341,9 @@ void register_irq_proc(unsigned int irq,
 | |
| + 	void __maybe_unused *irqp = (void *)(unsigned long) irq;
 | |
| + 	char name [MAX_NAMELEN];
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
 | |
| ++		return;
 | |
| ++
 | |
| + 	if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
 | |
| + 		return;
 | |
| + 
 | |
| +@@ -394,6 +397,9 @@ void unregister_irq_proc(unsigned int ir
 | |
| + {
 | |
| + 	char name [MAX_NAMELEN];
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
 | |
| ++		return;
 | |
| ++
 | |
| + 	if (!root_irq_dir || !desc->dir)
 | |
| + 		return;
 | |
| + #ifdef CONFIG_SMP
 | |
| +@@ -432,6 +438,9 @@ void init_irq_proc(void)
 | |
| + 	unsigned int irq;
 | |
| + 	struct irq_desc *desc;
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED) && !IS_ENABLED(CONFIG_SMP))
 | |
| ++		return;
 | |
| ++
 | |
| + 	/* create /proc/irq */
 | |
| + 	root_irq_dir = proc_mkdir("irq", NULL);
 | |
| + 	if (!root_irq_dir)
 | |
| +--- a/kernel/time/timer_list.c
 | |
| ++++ b/kernel/time/timer_list.c
 | |
| +@@ -370,6 +370,8 @@ static int __init init_timer_list_procfs
 | |
| + {
 | |
| + 	struct proc_dir_entry *pe;
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| + 	pe = proc_create_seq_private("timer_list", 0400, NULL, &timer_list_sops,
 | |
| + 			sizeof(struct timer_list_iter), NULL);
 | |
| + 	if (!pe)
 | |
| +--- a/mm/vmalloc.c
 | |
| ++++ b/mm/vmalloc.c
 | |
| +@@ -3572,6 +3572,8 @@ static const struct seq_operations vmall
 | |
| + 
 | |
| + static int __init proc_vmalloc_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| + 	if (IS_ENABLED(CONFIG_NUMA))
 | |
| + 		proc_create_seq_private("vmallocinfo", 0400, NULL,
 | |
| + 				&vmalloc_op,
 | |
| +--- a/mm/vmstat.c
 | |
| ++++ b/mm/vmstat.c
 | |
| +@@ -2044,10 +2044,12 @@ void __init init_mm_internals(void)
 | |
| + 	start_shepherd_timer();
 | |
| + #endif
 | |
| + #ifdef CONFIG_PROC_FS
 | |
| +-	proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
 | |
| +-	proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
 | |
| ++		proc_create_seq("buddyinfo", 0444, NULL, &fragmentation_op);
 | |
| ++		proc_create_seq("pagetypeinfo", 0400, NULL, &pagetypeinfo_op);
 | |
| ++		proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
 | |
| ++	}
 | |
| + 	proc_create_seq("vmstat", 0444, NULL, &vmstat_op);
 | |
| +-	proc_create_seq("zoneinfo", 0444, NULL, &zoneinfo_op);
 | |
| + #endif
 | |
| + }
 | |
| + 
 | |
| +--- a/net/8021q/vlanproc.c
 | |
| ++++ b/net/8021q/vlanproc.c
 | |
| +@@ -93,6 +93,9 @@ void vlan_proc_cleanup(struct net *net)
 | |
| + {
 | |
| + 	struct vlan_net *vn = net_generic(net, vlan_net_id);
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return;
 | |
| ++
 | |
| + 	if (vn->proc_vlan_conf)
 | |
| + 		remove_proc_entry(name_conf, vn->proc_vlan_dir);
 | |
| + 
 | |
| +@@ -112,6 +115,9 @@ int __net_init vlan_proc_init(struct net
 | |
| + {
 | |
| + 	struct vlan_net *vn = net_generic(net, vlan_net_id);
 | |
| + 
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| ++
 | |
| + 	vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
 | |
| + 	if (!vn->proc_vlan_dir)
 | |
| + 		goto err;
 | |
| +--- a/net/core/net-procfs.c
 | |
| ++++ b/net/core/net-procfs.c
 | |
| +@@ -290,10 +290,12 @@ static int __net_init dev_proc_net_init(
 | |
| + 	if (!proc_create_net("dev", 0444, net->proc_net, &dev_seq_ops,
 | |
| + 			sizeof(struct seq_net_private)))
 | |
| + 		goto out;
 | |
| +-	if (!proc_create_seq("softnet_stat", 0444, net->proc_net,
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
 | |
| ++			!proc_create_seq("softnet_stat", 0444, net->proc_net,
 | |
| + 			 &softnet_seq_ops))
 | |
| + 		goto out_dev;
 | |
| +-	if (!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
 | |
| ++			!proc_create_net("ptype", 0444, net->proc_net, &ptype_seq_ops,
 | |
| + 			sizeof(struct seq_net_private)))
 | |
| + 		goto out_softnet;
 | |
| + 
 | |
| +@@ -303,9 +305,11 @@ static int __net_init dev_proc_net_init(
 | |
| + out:
 | |
| + 	return rc;
 | |
| + out_ptype:
 | |
| +-	remove_proc_entry("ptype", net->proc_net);
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		remove_proc_entry("ptype", net->proc_net);
 | |
| + out_softnet:
 | |
| +-	remove_proc_entry("softnet_stat", net->proc_net);
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		remove_proc_entry("softnet_stat", net->proc_net);
 | |
| + out_dev:
 | |
| + 	remove_proc_entry("dev", net->proc_net);
 | |
| + 	goto out;
 | |
| +@@ -315,8 +319,10 @@ static void __net_exit dev_proc_net_exit
 | |
| + {
 | |
| + 	wext_proc_exit(net);
 | |
| + 
 | |
| +-	remove_proc_entry("ptype", net->proc_net);
 | |
| +-	remove_proc_entry("softnet_stat", net->proc_net);
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
 | |
| ++		remove_proc_entry("ptype", net->proc_net);
 | |
| ++		remove_proc_entry("softnet_stat", net->proc_net);
 | |
| ++	}
 | |
| + 	remove_proc_entry("dev", net->proc_net);
 | |
| + }
 | |
| + 
 | |
| +--- a/net/core/sock.c
 | |
| ++++ b/net/core/sock.c
 | |
| +@@ -3680,6 +3680,8 @@ static __net_initdata struct pernet_oper
 | |
| + 
 | |
| + static int __init proto_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| + 	return register_pernet_subsys(&proto_net_ops);
 | |
| + }
 | |
| + 
 | |
| +--- a/net/ipv4/fib_trie.c
 | |
| ++++ b/net/ipv4/fib_trie.c
 | |
| +@@ -2986,11 +2986,13 @@ static const struct seq_operations fib_r
 | |
| + 
 | |
| + int __net_init fib_proc_init(struct net *net)
 | |
| + {
 | |
| +-	if (!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
 | |
| ++			!proc_create_net("fib_trie", 0444, net->proc_net, &fib_trie_seq_ops,
 | |
| + 			sizeof(struct fib_trie_iter)))
 | |
| + 		goto out1;
 | |
| + 
 | |
| +-	if (!proc_create_net_single("fib_triestat", 0444, net->proc_net,
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED) &&
 | |
| ++			!proc_create_net_single("fib_triestat", 0444, net->proc_net,
 | |
| + 			fib_triestat_seq_show, NULL))
 | |
| + 		goto out2;
 | |
| + 
 | |
| +@@ -3001,17 +3003,21 @@ int __net_init fib_proc_init(struct net
 | |
| + 	return 0;
 | |
| + 
 | |
| + out3:
 | |
| +-	remove_proc_entry("fib_triestat", net->proc_net);
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		remove_proc_entry("fib_triestat", net->proc_net);
 | |
| + out2:
 | |
| +-	remove_proc_entry("fib_trie", net->proc_net);
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		remove_proc_entry("fib_trie", net->proc_net);
 | |
| + out1:
 | |
| + 	return -ENOMEM;
 | |
| + }
 | |
| + 
 | |
| + void __net_exit fib_proc_exit(struct net *net)
 | |
| + {
 | |
| +-	remove_proc_entry("fib_trie", net->proc_net);
 | |
| +-	remove_proc_entry("fib_triestat", net->proc_net);
 | |
| ++	if (!IS_ENABLED(CONFIG_PROC_STRIPPED)) {
 | |
| ++		remove_proc_entry("fib_trie", net->proc_net);
 | |
| ++		remove_proc_entry("fib_triestat", net->proc_net);
 | |
| ++	}
 | |
| + 	remove_proc_entry("route", net->proc_net);
 | |
| + }
 | |
| + 
 | |
| +--- a/net/ipv4/proc.c
 | |
| ++++ b/net/ipv4/proc.c
 | |
| +@@ -528,5 +528,8 @@ static __net_initdata struct pernet_oper
 | |
| + 
 | |
| + int __init ip_misc_proc_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| ++
 | |
| + 	return register_pernet_subsys(&ip_proc_ops);
 | |
| + }
 | |
| +--- a/net/ipv4/route.c
 | |
| ++++ b/net/ipv4/route.c
 | |
| +@@ -409,6 +409,9 @@ static struct pernet_operations ip_rt_pr
 | |
| + 
 | |
| + static int __init ip_rt_proc_init(void)
 | |
| + {
 | |
| ++	if (IS_ENABLED(CONFIG_PROC_STRIPPED))
 | |
| ++		return 0;
 | |
| ++
 | |
| + 	return register_pernet_subsys(&ip_rt_proc_ops);
 | |
| + }
 | |
| + 
 | |
| diff --git a/target/linux/generic/hack-5.10/904-debloat_dma_buf.patch b/target/linux/generic/hack-5.10/904-debloat_dma_buf.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2f5f685063
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/904-debloat_dma_buf.patch
 | |
| @@ -0,0 +1,82 @@
 | |
| +From e3692cb2fcd5ba1244512a0f43b8118f65f1c375 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sat, 8 Jul 2017 08:20:43 +0200
 | |
| +Subject: debloat: dmabuf
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/base/Kconfig      |  2 +-
 | |
| + drivers/dma-buf/Makefile  | 10 +++++++---
 | |
| + drivers/dma-buf/dma-buf.c |  4 +++-
 | |
| + kernel/sched/core.c       |  1 +
 | |
| + 4 files changed, 12 insertions(+), 5 deletions(-)
 | |
| +
 | |
| +--- a/drivers/base/Kconfig
 | |
| ++++ b/drivers/base/Kconfig
 | |
| +@@ -184,7 +184,7 @@ config SOC_BUS
 | |
| + source "drivers/base/regmap/Kconfig"
 | |
| + 
 | |
| + config DMA_SHARED_BUFFER
 | |
| +-	bool
 | |
| ++	tristate
 | |
| + 	default n
 | |
| + 	select IRQ_WORK
 | |
| + 	help
 | |
| +--- a/drivers/dma-buf/Makefile
 | |
| ++++ b/drivers/dma-buf/Makefile
 | |
| +@@ -1,15 +1,19 @@
 | |
| + # SPDX-License-Identifier: GPL-2.0-only
 | |
| +-obj-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
 | |
| ++obj-$(CONFIG_DMA_SHARED_BUFFER) := dma-shared-buffer.o
 | |
| ++
 | |
| ++dma-buf-objs-y := dma-buf.o dma-fence.o dma-fence-array.o dma-fence-chain.o \
 | |
| + 	 dma-resv.o seqno-fence.o
 | |
| +-obj-$(CONFIG_DMABUF_HEAPS)	+= dma-heap.o
 | |
| +-obj-$(CONFIG_DMABUF_HEAPS)	+= heaps/
 | |
| +-obj-$(CONFIG_SYNC_FILE)		+= sync_file.o
 | |
| +-obj-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o
 | |
| +-obj-$(CONFIG_UDMABUF)		+= udmabuf.o
 | |
| ++dma-buf-objs-$(CONFIG_DMABUF_HEAPS)	+= dma-heap.o
 | |
| ++dma-buf-objs-$(CONFIG_DMABUF_HEAPS)	+= heaps/
 | |
| ++dma-buf-objs-$(CONFIG_SYNC_FILE)		+= sync_file.o
 | |
| ++dma-buf-objs-$(CONFIG_SW_SYNC)		+= sw_sync.o sync_debug.o
 | |
| ++dma-buf-objs-$(CONFIG_UDMABUF)		+= udmabuf.o
 | |
| + 
 | |
| + dmabuf_selftests-y := \
 | |
| + 	selftest.o \
 | |
| + 	st-dma-fence.o \
 | |
| + 	st-dma-fence-chain.o
 | |
| + 
 | |
| +-obj-$(CONFIG_DMABUF_SELFTESTS)	+= dmabuf_selftests.o
 | |
| ++dma-buf-objs-$(CONFIG_DMABUF_SELFTESTS)	+= dmabuf_selftests.o
 | |
| ++
 | |
| ++dma-shared-buffer-objs :=  $(dma-buf-objs-y)
 | |
| +--- a/drivers/dma-buf/dma-buf.c
 | |
| ++++ b/drivers/dma-buf/dma-buf.c
 | |
| +@@ -1418,4 +1418,5 @@ static void __exit dma_buf_deinit(void)
 | |
| + 	dma_buf_uninit_debugfs();
 | |
| + 	kern_unmount(dma_buf_mnt);
 | |
| + }
 | |
| +-__exitcall(dma_buf_deinit);
 | |
| ++module_exit(dma_buf_deinit);
 | |
| ++MODULE_LICENSE("GPL");
 | |
| +--- a/kernel/sched/core.c
 | |
| ++++ b/kernel/sched/core.c
 | |
| +@@ -3051,6 +3051,7 @@ int wake_up_state(struct task_struct *p,
 | |
| + {
 | |
| + 	return try_to_wake_up(p, state, 0);
 | |
| + }
 | |
| ++EXPORT_SYMBOL_GPL(wake_up_state);
 | |
| + 
 | |
| + /*
 | |
| +  * Perform scheduler related setup for a newly forked process p.
 | |
| +--- a/fs/d_path.c
 | |
| ++++ b/fs/d_path.c
 | |
| +@@ -311,6 +311,7 @@ char *dynamic_dname(struct dentry *dentr
 | |
| + 	buffer += buflen - sz;
 | |
| + 	return memcpy(buffer, temp, sz);
 | |
| + }
 | |
| ++EXPORT_SYMBOL_GPL(dynamic_dname);
 | |
| + 
 | |
| + char *simple_dname(struct dentry *dentry, char *buffer, int buflen)
 | |
| + {
 | |
| diff --git a/target/linux/generic/hack-5.10/910-kobject_uevent.patch b/target/linux/generic/hack-5.10/910-kobject_uevent.patch
 | |
| new file mode 100644
 | |
| index 0000000000..c4c41ca400
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/910-kobject_uevent.patch
 | |
| @@ -0,0 +1,32 @@
 | |
| +From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sun, 16 Jul 2017 16:56:10 +0200
 | |
| +Subject: lib: add uevent_next_seqnum()
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/linux/kobject.h |  5 +++++
 | |
| + lib/kobject_uevent.c    | 37 +++++++++++++++++++++++++++++++++++++
 | |
| + 2 files changed, 42 insertions(+)
 | |
| +
 | |
| +--- a/lib/kobject_uevent.c
 | |
| ++++ b/lib/kobject_uevent.c
 | |
| +@@ -179,6 +179,18 @@ out:
 | |
| + 	return r;
 | |
| + }
 | |
| + 
 | |
| ++u64 uevent_next_seqnum(void)
 | |
| ++{
 | |
| ++	u64 seq;
 | |
| ++
 | |
| ++	mutex_lock(&uevent_sock_mutex);
 | |
| ++	seq = ++uevent_seqnum;
 | |
| ++	mutex_unlock(&uevent_sock_mutex);
 | |
| ++
 | |
| ++	return seq;
 | |
| ++}
 | |
| ++EXPORT_SYMBOL_GPL(uevent_next_seqnum);
 | |
| ++
 | |
| + /**
 | |
| +  * kobject_synth_uevent - send synthetic uevent with arguments
 | |
| +  *
 | |
| diff --git a/target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1f3002da4c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/hack-5.10/911-kobject_add_broadcast_uevent.patch
 | |
| @@ -0,0 +1,76 @@
 | |
| +From 0d37e6edc09c99e683dd91ca0e83bbc0df8477b3 Mon Sep 17 00:00:00 2001
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sun, 16 Jul 2017 16:56:10 +0200
 | |
| +Subject: lib: add uevent_next_seqnum()
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/linux/kobject.h |  5 +++++
 | |
| + lib/kobject_uevent.c    | 37 +++++++++++++++++++++++++++++++++++++
 | |
| + 2 files changed, 42 insertions(+)
 | |
| +
 | |
| +--- a/include/linux/kobject.h
 | |
| ++++ b/include/linux/kobject.h
 | |
| +@@ -32,6 +32,8 @@
 | |
| + #define UEVENT_NUM_ENVP			64	/* number of env pointers */
 | |
| + #define UEVENT_BUFFER_SIZE		2048	/* buffer for the variables */
 | |
| + 
 | |
| ++struct sk_buff;
 | |
| ++
 | |
| + #ifdef CONFIG_UEVENT_HELPER
 | |
| + /* path to the userspace helper executed on an event */
 | |
| + extern char uevent_helper[];
 | |
| +@@ -244,4 +246,7 @@ int kobject_synth_uevent(struct kobject
 | |
| + __printf(2, 3)
 | |
| + int add_uevent_var(struct kobj_uevent_env *env, const char *format, ...);
 | |
| + 
 | |
| ++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
 | |
| ++		     gfp_t allocation);
 | |
| ++
 | |
| + #endif /* _KOBJECT_H_ */
 | |
| +--- a/lib/kobject_uevent.c
 | |
| ++++ b/lib/kobject_uevent.c
 | |
| +@@ -690,6 +690,43 @@ int add_uevent_var(struct kobj_uevent_en
 | |
| + EXPORT_SYMBOL_GPL(add_uevent_var);
 | |
| + 
 | |
| + #if defined(CONFIG_NET)
 | |
| ++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
 | |
| ++		     gfp_t allocation)
 | |
| ++{
 | |
| ++	struct uevent_sock *ue_sk;
 | |
| ++	int err = 0;
 | |
| ++
 | |
| ++	/* send netlink message */
 | |
| ++	mutex_lock(&uevent_sock_mutex);
 | |
| ++	list_for_each_entry(ue_sk, &uevent_sock_list, list) {
 | |
| ++		struct sock *uevent_sock = ue_sk->sk;
 | |
| ++		struct sk_buff *skb2;
 | |
| ++
 | |
| ++		skb2 = skb_clone(skb, allocation);
 | |
| ++		if (!skb2)
 | |
| ++			break;
 | |
| ++
 | |
| ++		err = netlink_broadcast(uevent_sock, skb2, pid, group,
 | |
| ++					allocation);
 | |
| ++		if (err)
 | |
| ++			break;
 | |
| ++	}
 | |
| ++	mutex_unlock(&uevent_sock_mutex);
 | |
| ++
 | |
| ++	kfree_skb(skb);
 | |
| ++	return err;
 | |
| ++}
 | |
| ++#else
 | |
| ++int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
 | |
| ++		     gfp_t allocation)
 | |
| ++{
 | |
| ++	kfree_skb(skb);
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++#endif
 | |
| ++EXPORT_SYMBOL_GPL(broadcast_uevent);
 | |
| ++
 | |
| ++#if defined(CONFIG_NET)
 | |
| + static int uevent_net_broadcast(struct sock *usk, struct sk_buff *skb,
 | |
| + 				struct netlink_ext_ack *extack)
 | |
| + {
 | |
| diff --git a/target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch b/target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch
 | |
| new file mode 100644
 | |
| index 0000000000..39b98eac1b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/100-compiler.h-only-include-asm-rwonce.h-for-kernel-code.patch
 | |
| @@ -0,0 +1,29 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Thu, 22 Oct 2020 22:00:03 +0200
 | |
| +Subject: [PATCH] compiler.h: only include asm/rwonce.h for kernel code
 | |
| +
 | |
| +This header file is not in uapi, which makes any user space code that includes
 | |
| +linux/compiler.h to fail with the error 'asm/rwonce.h: No such file or directory'
 | |
| +
 | |
| +Fixes: e506ea451254 ("compiler.h: Split {READ,WRITE}_ONCE definitions out into rwonce.h")
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/compiler.h
 | |
| ++++ b/include/linux/compiler.h
 | |
| +@@ -211,6 +211,8 @@ void ftrace_likely_update(struct ftrace_
 | |
| + 	__v;								\
 | |
| + })
 | |
| + 
 | |
| ++#include <asm/rwonce.h>
 | |
| ++
 | |
| + #endif /* __KERNEL__ */
 | |
| + 
 | |
| + /*
 | |
| +@@ -243,6 +245,4 @@ static inline void *offset_to_ptr(const
 | |
| +  */
 | |
| + #define prevent_tail_call_optimization()	mb()
 | |
| + 
 | |
| +-#include <asm/rwonce.h>
 | |
| +-
 | |
| + #endif /* __LINUX_COMPILER_H */
 | |
| diff --git a/target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch b/target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch
 | |
| new file mode 100644
 | |
| index 0000000000..cc9f99e8b0
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/102-MIPS-only-process-negative-stack-offsets-on-stack-tr.patch
 | |
| @@ -0,0 +1,57 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Wed, 18 Apr 2018 10:50:05 +0200
 | |
| +Subject: [PATCH] MIPS: only process negative stack offsets on stack traces
 | |
| +
 | |
| +Fixes endless back traces in cases where the compiler emits a stack
 | |
| +pointer increase in a branch delay slot (probably for some form of
 | |
| +function return).
 | |
| +
 | |
| +[    3.475442] BUG: MAX_STACK_TRACE_ENTRIES too low!
 | |
| +[    3.480070] turning off the locking correctness validator.
 | |
| +[    3.485521] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.14.34 #0
 | |
| +[    3.491475] Stack : 00000000 00000000 00000000 00000000 80e0fce2 00000034 00000000 00000000
 | |
| +[    3.499764]         87c3838c 80696377 8061047c 00000000 00000001 00000001 87c2d850 6534689f
 | |
| +[    3.508059]         00000000 00000000 80e10000 00000000 00000000 000000cf 0000000f 00000000
 | |
| +[    3.516353]         00000000 806a0000 00076891 00000000 00000000 00000000 ffffffff 00000000
 | |
| +[    3.524648]         806c0000 00000004 80e10000 806a0000 00000003 80690000 00000000 80700000
 | |
| +[    3.532942]         ...
 | |
| +[    3.535362] Call Trace:
 | |
| +[    3.537818] [<80010a48>] show_stack+0x58/0x100
 | |
| +[    3.542207] [<804c2f78>] dump_stack+0xe8/0x170
 | |
| +[    3.546613] [<80079f90>] save_trace+0xf0/0x110
 | |
| +[    3.551010] [<8007b1ec>] mark_lock+0x33c/0x78c
 | |
| +[    3.555413] [<8007bf48>] __lock_acquire+0x2ac/0x1a08
 | |
| +[    3.560337] [<8007de60>] lock_acquire+0x64/0x8c
 | |
| +[    3.564846] [<804e1570>] _raw_spin_lock_irqsave+0x54/0x78
 | |
| +[    3.570186] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.574770] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.579257] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.583839] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.588329] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.592911] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.597401] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.601983] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.606473] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.611055] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.615545] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.620125] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.624619] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.629197] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.633691] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +[    3.638269] [<801b7b10>] sysfs_notify+0x74/0xa0
 | |
| +[    3.642763] [<801b618c>] kernfs_notify+0x94/0xac
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/arch/mips/kernel/process.c
 | |
| ++++ b/arch/mips/kernel/process.c
 | |
| +@@ -380,6 +380,8 @@ static inline int is_sp_move_ins(union m
 | |
| + 
 | |
| + 	if (ip->i_format.opcode == addiu_op ||
 | |
| + 	    ip->i_format.opcode == daddiu_op) {
 | |
| ++		if (ip->i_format.simmediate > 0)
 | |
| ++			return 0;
 | |
| + 		*frame_size = -ip->i_format.simmediate;
 | |
| + 		return 1;
 | |
| + 	}
 | |
| diff --git a/target/linux/generic/pending-5.10/103-MIPS-select-CPU_MIPS64-for-remaining-MIPS64-CPUs.patch b/target/linux/generic/pending-5.10/103-MIPS-select-CPU_MIPS64-for-remaining-MIPS64-CPUs.patch
 | |
| new file mode 100644
 | |
| index 0000000000..cf79e9a449
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/103-MIPS-select-CPU_MIPS64-for-remaining-MIPS64-CPUs.patch
 | |
| @@ -0,0 +1,36 @@
 | |
| +From 6523061868212473f63812a0c477a161742bed42 Mon Sep 17 00:00:00 2001
 | |
| +From: "Jason A. Donenfeld" <Jason@zx2c4.com>
 | |
| +Date: Sat, 27 Feb 2021 13:20:24 +0100
 | |
| +Subject: [PATCH] MIPS: select CPU_MIPS64 for remaining MIPS64 CPUs
 | |
| +
 | |
| +The CPU_MIPS64 and CPU_MIPS32 variables are supposed to be able to
 | |
| +distinguish broadly between 64-bit and 32-bit MIPS CPUs. However, they
 | |
| +weren't selected by the specialty CPUs, Octeon and Loongson, which meant
 | |
| +it was possible to hit a weird state of:
 | |
| +
 | |
| +    MIPS=y, CONFIG_64BIT=y, CPU_MIPS64=n
 | |
| +
 | |
| +This commit rectifies the issue by having CPU_MIPS64 be selected when
 | |
| +the missing Octeon or Loongson models are selected.
 | |
| +
 | |
| +Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 | |
| +Cc: Ralf Baechle <ralf@linux-mips.org>
 | |
| +Cc: George Cherian <gcherian@marvell.com>
 | |
| +Cc: Huacai Chen <chenhuacai@kernel.org>
 | |
| +Cc: Jiaxun Yang <jiaxun.yang@flygoat.com>
 | |
| +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
 | |
| +---
 | |
| + arch/mips/Kconfig | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/mips/Kconfig
 | |
| ++++ b/arch/mips/Kconfig
 | |
| +@@ -2075,7 +2075,7 @@ config CPU_MIPS32
 | |
| + config CPU_MIPS64
 | |
| + 	bool
 | |
| + 	default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 || CPU_MIPS64_R5 || \
 | |
| +-		     CPU_MIPS64_R6
 | |
| ++		     CPU_MIPS64_R6 || CPU_LOONGSON64 || CPU_CAVIUM_OCTEON
 | |
| + 
 | |
| + #
 | |
| + # These indicate the revision of the architecture
 | |
| diff --git a/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4375e727cf
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/120-Fix-alloc_node_mem_map-with-ARCH_PFN_OFFSET-calcu.patch
 | |
| @@ -0,0 +1,82 @@
 | |
| +From: Tobias Wolf <dev-NTEO@vplace.de>
 | |
| +Subject: mm: Fix alloc_node_mem_map with ARCH_PFN_OFFSET calculation
 | |
| +
 | |
| +An rt288x (ralink) based router (Belkin F5D8235 v1) does not boot with any
 | |
| +kernel beyond version 4.3 resulting in:
 | |
| +
 | |
| +BUG: Bad page state in process swapper  pfn:086ac
 | |
| +
 | |
| +bisect resulted in:
 | |
| +
 | |
| +a1c34a3bf00af2cede839879502e12dc68491ad5 is the first bad commit
 | |
| +commit a1c34a3bf00af2cede839879502e12dc68491ad5
 | |
| +Author: Laura Abbott <laura@labbott.name>
 | |
| +Date:   Thu Nov 5 18:48:46 2015 -0800
 | |
| +
 | |
| +    mm: Don't offset memmap for flatmem
 | |
| +
 | |
| +    Srinivas Kandagatla reported bad page messages when trying to remove the
 | |
| +    bottom 2MB on an ARM based IFC6410 board
 | |
| +
 | |
| +      BUG: Bad page state in process swapper  pfn:fffa8
 | |
| +      page:ef7fb500 count:0 mapcount:0 mapping:  (null) index:0x0
 | |
| +      flags: 0x96640253(locked|error|dirty|active|arch_1|reclaim|mlocked)
 | |
| +      page dumped because: PAGE_FLAGS_CHECK_AT_FREE flag(s) set
 | |
| +      bad because of flags:
 | |
| +      flags: 0x200041(locked|active|mlocked)
 | |
| +      Modules linked in:
 | |
| +      CPU: 0 PID: 0 Comm: swapper Not tainted 3.19.0-rc3-00007-g412f9ba-dirty
 | |
| +#816
 | |
| +      Hardware name: Qualcomm (Flattened Device Tree)
 | |
| +        unwind_backtrace
 | |
| +        show_stack
 | |
| +        dump_stack
 | |
| +        bad_page
 | |
| +        free_pages_prepare
 | |
| +        free_hot_cold_page
 | |
| +        __free_pages
 | |
| +        free_highmem_page
 | |
| +        mem_init
 | |
| +        start_kernel
 | |
| +      Disabling lock debugging due to kernel taint
 | |
| +    [...]
 | |
| +:040000 040000 2de013c372345fd471cd58f0553c9b38b0ef1cc4
 | |
| +0a8156f848733dfa21e16c196dfb6c0a76290709 M      mm
 | |
| +
 | |
| +This fix for ARM does not account ARCH_PFN_OFFSET for mem_map as later used by
 | |
| +page_to_pfn anymore.
 | |
| +
 | |
| +The following output was generated with two hacked in printk statements:
 | |
| +
 | |
| +printk("before %p vs. %p or %p\n", mem_map, mem_map - offset, mem_map -
 | |
| +(pgdat->node_start_pfn - ARCH_PFN_OFFSET));
 | |
| +		if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
 | |
| +			mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
 | |
| +printk("after %p\n", mem_map);
 | |
| +
 | |
| +Output:
 | |
| +
 | |
| +[    0.000000] before 8861b280 vs. 8861b280 or 8851b280
 | |
| +[    0.000000] after 8851b280
 | |
| +
 | |
| +As seen in the first line mem_map with subtraction of offset does not equal the
 | |
| +mem_map after subtraction of ARCH_PFN_OFFSET.
 | |
| +
 | |
| +After adding the offset of ARCH_PFN_OFFSET as well to mem_map as the
 | |
| +previously calculated offset is zero for the named platform it is able to boot
 | |
| +4.4 and 4.9-rc7 again.
 | |
| +
 | |
| +Signed-off-by: Tobias Wolf <dev-NTEO@vplace.de>
 | |
| +---
 | |
| +
 | |
| +--- a/mm/page_alloc.c
 | |
| ++++ b/mm/page_alloc.c
 | |
| +@@ -7027,7 +7027,7 @@ static void __ref alloc_node_mem_map(str
 | |
| + 	if (pgdat == NODE_DATA(0)) {
 | |
| + 		mem_map = NODE_DATA(0)->node_mem_map;
 | |
| + 		if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
 | |
| +-			mem_map -= offset;
 | |
| ++			mem_map -= offset + (pgdat->node_start_pfn - ARCH_PFN_OFFSET);
 | |
| + 	}
 | |
| + #endif
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch b/target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch
 | |
| new file mode 100644
 | |
| index 0000000000..355e900a3b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/130-add-linux-spidev-compatible-si3210.patch
 | |
| @@ -0,0 +1,18 @@
 | |
| +From: Giuseppe Lippolis <giu.lippolis@gmail.com>
 | |
| +Subject: Add the linux,spidev compatible in spidev Several device in ramips have this binding in the dts
 | |
| +
 | |
| +Signed-off-by: Giuseppe Lippolis <giu.lippolis@gmail.com>
 | |
| +---
 | |
| + drivers/spi/spidev.c | 1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/drivers/spi/spidev.c
 | |
| ++++ b/drivers/spi/spidev.c
 | |
| +@@ -682,6 +682,7 @@ static const struct of_device_id spidev_
 | |
| + 	{ .compatible = "lwn,bk4" },
 | |
| + 	{ .compatible = "dh,dhcom-board" },
 | |
| + 	{ .compatible = "menlo,m53cpld" },
 | |
| ++	{ .compatible = "siliconlabs,si3210" },
 | |
| + 	{},
 | |
| + };
 | |
| + MODULE_DEVICE_TABLE(of, spidev_dt_ids);
 | |
| diff --git a/target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch b/target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e48da41fae
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch
 | |
| @@ -0,0 +1,78 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support
 | |
| +
 | |
| +It is required for renames on overlayfs
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/fs/jffs2/dir.c
 | |
| ++++ b/fs/jffs2/dir.c
 | |
| +@@ -609,7 +609,8 @@ static int jffs2_rmdir (struct inode *di
 | |
| + 	return ret;
 | |
| + }
 | |
| + 
 | |
| +-static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev)
 | |
| ++static int __jffs2_mknod (struct inode *dir_i, struct dentry *dentry,
 | |
| ++			  umode_t mode, dev_t rdev, bool whiteout)
 | |
| + {
 | |
| + 	struct jffs2_inode_info *f, *dir_f;
 | |
| + 	struct jffs2_sb_info *c;
 | |
| +@@ -748,7 +749,11 @@ static int jffs2_mknod (struct inode *di
 | |
| + 	mutex_unlock(&dir_f->sem);
 | |
| + 	jffs2_complete_reservation(c);
 | |
| + 
 | |
| +-	d_instantiate_new(dentry, inode);
 | |
| ++	if (!whiteout)
 | |
| ++		d_instantiate_new(dentry, inode);
 | |
| ++	else
 | |
| ++		unlock_new_inode(inode);
 | |
| ++
 | |
| + 	return 0;
 | |
| + 
 | |
| +  fail:
 | |
| +@@ -756,6 +761,17 @@ static int jffs2_mknod (struct inode *di
 | |
| + 	return ret;
 | |
| + }
 | |
| + 
 | |
| ++static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, umode_t mode, dev_t rdev)
 | |
| ++{
 | |
| ++	return __jffs2_mknod(dir_i, dentry, mode, rdev, false);
 | |
| ++}
 | |
| ++
 | |
| ++static int jffs2_whiteout (struct inode *old_dir, struct dentry *old_dentry)
 | |
| ++{
 | |
| ++	return __jffs2_mknod(old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE,
 | |
| ++			     WHITEOUT_DEV, true);
 | |
| ++}
 | |
| ++
 | |
| + static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
 | |
| + 			 struct inode *new_dir_i, struct dentry *new_dentry,
 | |
| + 			 unsigned int flags)
 | |
| +@@ -766,7 +782,7 @@ static int jffs2_rename (struct inode *o
 | |
| + 	uint8_t type;
 | |
| + 	uint32_t now;
 | |
| + 
 | |
| +-	if (flags & ~RENAME_NOREPLACE)
 | |
| ++	if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
 | |
| + 		return -EINVAL;
 | |
| + 
 | |
| + 	/* The VFS will check for us and prevent trying to rename a
 | |
| +@@ -832,9 +848,14 @@ static int jffs2_rename (struct inode *o
 | |
| + 	if (d_is_dir(old_dentry) && !victim_f)
 | |
| + 		inc_nlink(new_dir_i);
 | |
| + 
 | |
| +-	/* Unlink the original */
 | |
| +-	ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
 | |
| +-			      old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
 | |
| ++	if (flags & RENAME_WHITEOUT)
 | |
| ++		/* Replace with whiteout */
 | |
| ++		ret = jffs2_whiteout(old_dir_i, old_dentry);
 | |
| ++	else
 | |
| ++		/* Unlink the original */
 | |
| ++		ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
 | |
| ++				      old_dentry->d_name.name,
 | |
| ++				      old_dentry->d_name.len, NULL, now);
 | |
| + 
 | |
| + 	/* We don't touch inode->i_nlink */
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch b/target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..dbc72339c6
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/141-jffs2-add-RENAME_EXCHANGE-support.patch
 | |
| @@ -0,0 +1,73 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: jffs2: add RENAME_EXCHANGE support
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/fs/jffs2/dir.c
 | |
| ++++ b/fs/jffs2/dir.c
 | |
| +@@ -779,18 +779,31 @@ static int jffs2_rename (struct inode *o
 | |
| + 	int ret;
 | |
| + 	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
 | |
| + 	struct jffs2_inode_info *victim_f = NULL;
 | |
| ++	struct inode *fst_inode = d_inode(old_dentry);
 | |
| ++	struct inode *snd_inode = d_inode(new_dentry);
 | |
| + 	uint8_t type;
 | |
| + 	uint32_t now;
 | |
| + 
 | |
| +-	if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
 | |
| ++	if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT|RENAME_EXCHANGE))
 | |
| + 		return -EINVAL;
 | |
| + 
 | |
| ++	if ((flags & RENAME_EXCHANGE) && (old_dir_i != new_dir_i)) {
 | |
| ++		if (S_ISDIR(fst_inode->i_mode) && !S_ISDIR(snd_inode->i_mode)) {
 | |
| ++			inc_nlink(new_dir_i);
 | |
| ++			drop_nlink(old_dir_i);
 | |
| ++		}
 | |
| ++		else if (!S_ISDIR(fst_inode->i_mode) && S_ISDIR(snd_inode->i_mode)) {
 | |
| ++			drop_nlink(new_dir_i);
 | |
| ++			inc_nlink(old_dir_i);
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| + 	/* The VFS will check for us and prevent trying to rename a
 | |
| + 	 * file over a directory and vice versa, but if it's a directory,
 | |
| + 	 * the VFS can't check whether the victim is empty. The filesystem
 | |
| + 	 * needs to do that for itself.
 | |
| + 	 */
 | |
| +-	if (d_really_is_positive(new_dentry)) {
 | |
| ++	if (d_really_is_positive(new_dentry) && !(flags & RENAME_EXCHANGE)) {
 | |
| + 		victim_f = JFFS2_INODE_INFO(d_inode(new_dentry));
 | |
| + 		if (d_is_dir(new_dentry)) {
 | |
| + 			struct jffs2_full_dirent *fd;
 | |
| +@@ -825,7 +838,7 @@ static int jffs2_rename (struct inode *o
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| +-	if (victim_f) {
 | |
| ++	if (victim_f && !(flags & RENAME_EXCHANGE)) {
 | |
| + 		/* There was a victim. Kill it off nicely */
 | |
| + 		if (d_is_dir(new_dentry))
 | |
| + 			clear_nlink(d_inode(new_dentry));
 | |
| +@@ -851,6 +864,12 @@ static int jffs2_rename (struct inode *o
 | |
| + 	if (flags & RENAME_WHITEOUT)
 | |
| + 		/* Replace with whiteout */
 | |
| + 		ret = jffs2_whiteout(old_dir_i, old_dentry);
 | |
| ++	else if (flags & RENAME_EXCHANGE)
 | |
| ++		/* Replace the original */
 | |
| ++		ret = jffs2_do_link(c, JFFS2_INODE_INFO(old_dir_i),
 | |
| ++				    d_inode(new_dentry)->i_ino, type,
 | |
| ++				    old_dentry->d_name.name, old_dentry->d_name.len,
 | |
| ++				    now);
 | |
| + 	else
 | |
| + 		/* Unlink the original */
 | |
| + 		ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
 | |
| +@@ -882,7 +901,7 @@ static int jffs2_rename (struct inode *o
 | |
| + 		return ret;
 | |
| + 	}
 | |
| + 
 | |
| +-	if (d_is_dir(old_dentry))
 | |
| ++	if (d_is_dir(old_dentry) && !(flags & RENAME_EXCHANGE))
 | |
| + 		drop_nlink(old_dir_i);
 | |
| + 
 | |
| + 	new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
 | |
| diff --git a/target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch b/target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch
 | |
| new file mode 100644
 | |
| index 0000000000..de847a1f5c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/142-jffs2-add-splice-ops.patch
 | |
| @@ -0,0 +1,20 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: jffs2: add splice ops
 | |
| +
 | |
| +Add splice_read using generic_file_splice_read.
 | |
| +Add splice_write using iter_file_splice_write
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/fs/jffs2/file.c
 | |
| ++++ b/fs/jffs2/file.c
 | |
| +@@ -53,6 +53,8 @@ const struct file_operations jffs2_file_
 | |
| + 	.open =		generic_file_open,
 | |
| +  	.read_iter =	generic_file_read_iter,
 | |
| +  	.write_iter =	generic_file_write_iter,
 | |
| ++	.splice_read =	generic_file_splice_read,
 | |
| ++	.splice_write =	iter_file_splice_write,
 | |
| + 	.unlocked_ioctl=jffs2_ioctl,
 | |
| + 	.mmap =		generic_file_readonly_mmap,
 | |
| + 	.fsync =	jffs2_fsync,
 | |
| diff --git a/target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch b/target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch
 | |
| new file mode 100644
 | |
| index 0000000000..6de22b1c7d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/150-bridge_allow_receiption_on_disabled_port.patch
 | |
| @@ -0,0 +1,45 @@
 | |
| +From: Stephen Hemminger <stephen@networkplumber.org>
 | |
| +Subject: bridge: allow receiption on disabled port
 | |
| +
 | |
| +When an ethernet device is enslaved to a bridge, and the bridge STP
 | |
| +detects loss of carrier (or operational state down), then normally
 | |
| +packet receiption is blocked.
 | |
| +
 | |
| +This breaks control applications like WPA which maybe expecting to
 | |
| +receive packets to negotiate to bring link up. The bridge needs to
 | |
| +block forwarding packets from these disabled ports, but there is no
 | |
| +hard requirement to not allow local packet delivery.
 | |
| +
 | |
| +Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +
 | |
| +--- a/net/bridge/br_input.c
 | |
| ++++ b/net/bridge/br_input.c
 | |
| +@@ -195,6 +195,9 @@ static void __br_handle_local_finish(str
 | |
| + /* note: already called with rcu_read_lock */
 | |
| + static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
 | |
| + {
 | |
| ++	struct net_bridge_port *p = br_port_get_rcu(skb->dev);
 | |
| ++
 | |
| ++	if (p->state != BR_STATE_DISABLED)
 | |
| + 	__br_handle_local_finish(skb);
 | |
| + 
 | |
| + 	/* return 1 to signal the okfn() was called so it's ok to use the skb */
 | |
| +@@ -348,6 +351,17 @@ static rx_handler_result_t br_handle_fra
 | |
| + 
 | |
| + forward:
 | |
| + 	switch (p->state) {
 | |
| ++	case BR_STATE_DISABLED:
 | |
| ++		if (ether_addr_equal(p->br->dev->dev_addr, dest))
 | |
| ++			skb->pkt_type = PACKET_HOST;
 | |
| ++
 | |
| ++		if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING,
 | |
| ++			dev_net(skb->dev), NULL, skb, skb->dev, NULL,
 | |
| ++			br_handle_local_finish) == 1) {
 | |
| ++			return RX_HANDLER_PASS;
 | |
| ++		}
 | |
| ++		break;
 | |
| ++
 | |
| + 	case BR_STATE_FORWARDING:
 | |
| + 	case BR_STATE_LEARNING:
 | |
| + 		if (ether_addr_equal(p->br->dev->dev_addr, dest))
 | |
| diff --git a/target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch b/target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch
 | |
| new file mode 100644
 | |
| index 0000000000..13b79b5c09
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/190-rtc-rs5c372-support_alarms_up_to_1_week.patch
 | |
| @@ -0,0 +1,94 @@
 | |
| +From: Daniel González Cabanelas <dgcbueu@gmail.com>
 | |
| +Subject: [PATCH 1/2] rtc: rs5c372: support alarms up to 1 week
 | |
| +
 | |
| +The Ricoh R2221x, R2223x, RS5C372, RV5C387A chips can handle 1 week
 | |
| +alarms.
 | |
| +
 | |
| +Read the "wday" alarm register and convert it to a date to support up 1
 | |
| +week in our driver.
 | |
| +
 | |
| +Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
 | |
| +---
 | |
| + drivers/rtc/rtc-rs5c372.c | 48 ++++++++++++++++++++++++++++++++++-----
 | |
| + 1 file changed, 42 insertions(+), 6 deletions(-)
 | |
| +
 | |
| +--- a/drivers/rtc/rtc-rs5c372.c
 | |
| ++++ b/drivers/rtc/rtc-rs5c372.c
 | |
| +@@ -393,7 +393,9 @@ static int rs5c_read_alarm(struct device
 | |
| + {
 | |
| + 	struct i2c_client	*client = to_i2c_client(dev);
 | |
| + 	struct rs5c372		*rs5c = i2c_get_clientdata(client);
 | |
| +-	int			status;
 | |
| ++	int			status, wday_offs;
 | |
| ++	struct rtc_time 	rtc;
 | |
| ++	unsigned long 		alarm_secs;
 | |
| + 
 | |
| + 	status = rs5c_get_regs(rs5c);
 | |
| + 	if (status < 0)
 | |
| +@@ -403,6 +405,30 @@ static int rs5c_read_alarm(struct device
 | |
| + 	t->time.tm_sec = 0;
 | |
| + 	t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
 | |
| + 	t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]);
 | |
| ++	t->time.tm_wday = ffs(rs5c->regs[RS5C_REG_ALARM_A_WDAY] & 0x7f) - 1;
 | |
| ++
 | |
| ++	/* determine the day, month and year based on alarm wday, taking as a
 | |
| ++	 * reference the current time from the rtc
 | |
| ++	 */
 | |
| ++	status = rs5c372_rtc_read_time(dev, &rtc);
 | |
| ++	if (status < 0)
 | |
| ++		return status;
 | |
| ++
 | |
| ++	wday_offs = t->time.tm_wday - rtc.tm_wday;
 | |
| ++	alarm_secs = mktime64(rtc.tm_year + 1900,
 | |
| ++			      rtc.tm_mon + 1,
 | |
| ++			      rtc.tm_mday + wday_offs,
 | |
| ++			      t->time.tm_hour,
 | |
| ++			      t->time.tm_min,
 | |
| ++			      t->time.tm_sec);
 | |
| ++
 | |
| ++	if (wday_offs < 0 || (wday_offs == 0 &&
 | |
| ++			      (t->time.tm_hour < rtc.tm_hour ||
 | |
| ++			       (t->time.tm_hour == rtc.tm_hour &&
 | |
| ++				t->time.tm_min <= rtc.tm_min))))
 | |
| ++		alarm_secs += 7 * 86400;
 | |
| ++
 | |
| ++	rtc_time64_to_tm(alarm_secs, &t->time);
 | |
| + 
 | |
| + 	/* ... and status */
 | |
| + 	t->enabled = !!(rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE);
 | |
| +@@ -417,12 +443,20 @@ static int rs5c_set_alarm(struct device
 | |
| + 	struct rs5c372		*rs5c = i2c_get_clientdata(client);
 | |
| + 	int			status, addr, i;
 | |
| + 	unsigned char		buf[3];
 | |
| ++	struct rtc_time 	rtc_tm;
 | |
| ++	unsigned long 		rtc_secs, alarm_secs;
 | |
| + 
 | |
| +-	/* only handle up to 24 hours in the future, like RTC_ALM_SET */
 | |
| +-	if (t->time.tm_mday != -1
 | |
| +-			|| t->time.tm_mon != -1
 | |
| +-			|| t->time.tm_year != -1)
 | |
| ++	/* chip only can handle alarms up to one week in the future*/
 | |
| ++	status = rs5c372_rtc_read_time(dev, &rtc_tm);
 | |
| ++	if (status)
 | |
| ++		return status;
 | |
| ++	rtc_secs = rtc_tm_to_time64(&rtc_tm);
 | |
| ++	alarm_secs = rtc_tm_to_time64(&t->time);
 | |
| ++	if (alarm_secs >= rtc_secs + 7 * 86400) {
 | |
| ++		dev_err(dev, "%s: alarm maximum is one week in the future (%d)\n",
 | |
| ++			__func__, status);
 | |
| + 		return -EINVAL;
 | |
| ++	}
 | |
| + 
 | |
| + 	/* REVISIT: round up tm_sec */
 | |
| + 
 | |
| +@@ -443,7 +477,9 @@ static int rs5c_set_alarm(struct device
 | |
| + 	/* set alarm */
 | |
| + 	buf[0] = bin2bcd(t->time.tm_min);
 | |
| + 	buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
 | |
| +-	buf[2] = 0x7f;	/* any/all days */
 | |
| ++	/* each bit is the day of the week, 0x7f means all days */
 | |
| ++	buf[2] = (t->time.tm_wday >= 0 && t->time.tm_wday < 7) ?
 | |
| ++		  BIT(t->time.tm_wday) : 0x7f;
 | |
| + 
 | |
| + 	for (i = 0; i < sizeof(buf); i++) {
 | |
| + 		addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
 | |
| diff --git a/target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch b/target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch
 | |
| new file mode 100644
 | |
| index 0000000000..7e9d0e66c0
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/191-rtc-rs5c372-let_the_alarm_to_be_used_as_wakeup_source.patch
 | |
| @@ -0,0 +1,70 @@
 | |
| +From: Daniel González Cabanelas <dgcbueu@gmail.com>
 | |
| +Subject: [PATCH 2/2] rtc: rs5c372: let the alarm to be used as wakeup source
 | |
| +
 | |
| +Currently there is no use for the interrupts on the rs5c372 RTC and the
 | |
| +wakealarm isn't enabled. There are some devices like NASes which use this
 | |
| +RTC to wake up from the power off state when the INTR pin is activated by
 | |
| +the alarm clock.
 | |
| +
 | |
| +Enable the alarm and let to be used as a wakeup source.
 | |
| +
 | |
| +Tested on a Buffalo LS421DE NAS.
 | |
| +
 | |
| +Signed-off-by: Daniel González Cabanelas <dgcbueu@gmail.com>
 | |
| +---
 | |
| + drivers/rtc/rtc-rs5c372.c | 16 ++++++++++++++++
 | |
| + 1 file changed, 16 insertions(+)
 | |
| +
 | |
| +--- a/drivers/rtc/rtc-rs5c372.c
 | |
| ++++ b/drivers/rtc/rtc-rs5c372.c
 | |
| +@@ -654,6 +654,7 @@ static int rs5c372_probe(struct i2c_clie
 | |
| + 	int err = 0;
 | |
| + 	int smbus_mode = 0;
 | |
| + 	struct rs5c372 *rs5c372;
 | |
| ++	bool rs5c372_can_wakeup_device = false;
 | |
| + 
 | |
| + 	dev_dbg(&client->dev, "%s\n", __func__);
 | |
| + 
 | |
| +@@ -689,6 +690,12 @@ static int rs5c372_probe(struct i2c_clie
 | |
| + 	else
 | |
| + 		rs5c372->type = id->driver_data;
 | |
| + 
 | |
| ++#ifdef CONFIG_OF
 | |
| ++	if(of_property_read_bool(client->dev.of_node,
 | |
| ++					      "wakeup-source"))
 | |
| ++		rs5c372_can_wakeup_device = true;
 | |
| ++#endif
 | |
| ++
 | |
| + 	/* we read registers 0x0f then 0x00-0x0f; skip the first one */
 | |
| + 	rs5c372->regs = &rs5c372->buf[1];
 | |
| + 	rs5c372->smbus = smbus_mode;
 | |
| +@@ -722,6 +729,8 @@ static int rs5c372_probe(struct i2c_clie
 | |
| + 		goto exit;
 | |
| + 	}
 | |
| + 
 | |
| ++	rs5c372->has_irq = 1;
 | |
| ++
 | |
| + 	/* if the oscillator lost power and no other software (like
 | |
| + 	 * the bootloader) set it up, do it here.
 | |
| + 	 *
 | |
| +@@ -748,6 +757,10 @@ static int rs5c372_probe(struct i2c_clie
 | |
| + 			);
 | |
| + 
 | |
| + 	/* REVISIT use client->irq to register alarm irq ... */
 | |
| ++	if (rs5c372_can_wakeup_device) {
 | |
| ++		device_init_wakeup(&client->dev, true);
 | |
| ++	}
 | |
| ++
 | |
| + 	rs5c372->rtc = devm_rtc_device_register(&client->dev,
 | |
| + 					rs5c372_driver.driver.name,
 | |
| + 					&rs5c372_rtc_ops, THIS_MODULE);
 | |
| +@@ -761,6 +774,9 @@ static int rs5c372_probe(struct i2c_clie
 | |
| + 	if (err)
 | |
| + 		goto exit;
 | |
| + 
 | |
| ++	/* the rs5c372 alarm only supports a minute accuracy */
 | |
| ++	rs5c372->rtc->uie_unsupported = 1;
 | |
| ++
 | |
| + 	return 0;
 | |
| + 
 | |
| + exit:
 | |
| diff --git a/target/linux/generic/pending-5.10/201-extra_optimization.patch b/target/linux/generic/pending-5.10/201-extra_optimization.patch
 | |
| new file mode 100644
 | |
| index 0000000000..df973258ab
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/201-extra_optimization.patch
 | |
| @@ -0,0 +1,31 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: Upgrade to Linux 2.6.19
 | |
| +
 | |
| +- Includes large parts of the patch from #1021 by dpalffy
 | |
| +- Includes RB532 NAND driver changes by n0-1
 | |
| +
 | |
| +[john@phrozen.org: feix will add this to his upstream queue]
 | |
| +
 | |
| +lede-commit: bff468813f78f81e36ebb2a3f4354de7365e640f
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + Makefile | 6 +++---
 | |
| + 1 file changed, 3 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/Makefile
 | |
| ++++ b/Makefile
 | |
| +@@ -734,11 +734,11 @@ KBUILD_CFLAGS	+= $(call cc-disable-warni
 | |
| + KBUILD_CFLAGS	+= $(call cc-disable-warning, address-of-packed-member)
 | |
| + 
 | |
| + ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
 | |
| +-KBUILD_CFLAGS += -O2
 | |
| ++KBUILD_CFLAGS += -O2 $(EXTRA_OPTIMIZATION)
 | |
| + else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
 | |
| +-KBUILD_CFLAGS += -O3
 | |
| ++KBUILD_CFLAGS += -O3 $(EXTRA_OPTIMIZATION)
 | |
| + else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
 | |
| +-KBUILD_CFLAGS += -Os
 | |
| ++KBUILD_CFLAGS += -Os -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION)
 | |
| + endif
 | |
| + 
 | |
| + # Tell gcc to never replace conditional load with a non-conditional one
 | |
| diff --git a/target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch b/target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch
 | |
| new file mode 100644
 | |
| index 0000000000..9f2014c8ec
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/203-kallsyms_uncompressed.patch
 | |
| @@ -0,0 +1,119 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: kernel: add a config option for keeping the kallsyms table uncompressed, saving ~9kb kernel size after lzma on ar71xx
 | |
| +
 | |
| +[john@phrozen.org: added to my upstream queue 30.12.2016]
 | |
| +lede-commit: e0e3509b5ce2ccf93d4d67ea907613f5f7ec2eed
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + init/Kconfig            | 11 +++++++++++
 | |
| + kernel/kallsyms.c       |  8 ++++++++
 | |
| + scripts/kallsyms.c      | 12 ++++++++++++
 | |
| + scripts/link-vmlinux.sh |  4 ++++
 | |
| + 4 files changed, 35 insertions(+)
 | |
| +
 | |
| +--- a/init/Kconfig
 | |
| ++++ b/init/Kconfig
 | |
| +@@ -1385,6 +1385,17 @@ config SYSCTL_ARCH_UNALIGN_ALLOW
 | |
| + 	  the unaligned access emulation.
 | |
| + 	  see arch/parisc/kernel/unaligned.c for reference
 | |
| + 
 | |
| ++config KALLSYMS_UNCOMPRESSED
 | |
| ++	bool "Keep kallsyms uncompressed"
 | |
| ++	depends on KALLSYMS
 | |
| ++	help
 | |
| ++		Normally kallsyms contains compressed symbols (using a token table),
 | |
| ++		reducing the uncompressed kernel image size. Keeping the symbol table
 | |
| ++		uncompressed significantly improves the size of this part in compressed
 | |
| ++		kernel images.
 | |
| ++
 | |
| ++		Say N unless you need compressed kernel images to be small.
 | |
| ++
 | |
| + config HAVE_PCSPKR_PLATFORM
 | |
| + 	bool
 | |
| + 
 | |
| +--- a/kernel/kallsyms.c
 | |
| ++++ b/kernel/kallsyms.c
 | |
| +@@ -77,6 +77,11 @@ static unsigned int kallsyms_expand_symb
 | |
| + 	 * For every byte on the compressed symbol data, copy the table
 | |
| + 	 * entry for that byte.
 | |
| + 	 */
 | |
| ++#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
 | |
| ++	memcpy(result, data + 1, len - 1);
 | |
| ++	result += len - 1;
 | |
| ++	len = 0;
 | |
| ++#endif
 | |
| + 	while (len) {
 | |
| + 		tptr = &kallsyms_token_table[kallsyms_token_index[*data]];
 | |
| + 		data++;
 | |
| +@@ -109,6 +114,9 @@ tail:
 | |
| +  */
 | |
| + static char kallsyms_get_symbol_type(unsigned int off)
 | |
| + {
 | |
| ++#ifdef CONFIG_KALLSYMS_UNCOMPRESSED
 | |
| ++	return kallsyms_names[off + 1];
 | |
| ++#endif
 | |
| + 	/*
 | |
| + 	 * Get just the first code, look it up in the token table,
 | |
| + 	 * and return the first char from this token.
 | |
| +--- a/scripts/kallsyms.c
 | |
| ++++ b/scripts/kallsyms.c
 | |
| +@@ -58,6 +58,7 @@ static struct addr_range percpu_range =
 | |
| + static struct sym_entry **table;
 | |
| + static unsigned int table_size, table_cnt;
 | |
| + static int all_symbols;
 | |
| ++static int uncompressed;
 | |
| + static int absolute_percpu;
 | |
| + static int base_relative;
 | |
| + 
 | |
| +@@ -486,6 +487,9 @@ static void write_src(void)
 | |
| + 
 | |
| + 	free(markers);
 | |
| + 
 | |
| ++	if (uncompressed)
 | |
| ++		return;
 | |
| ++
 | |
| + 	output_label("kallsyms_token_table");
 | |
| + 	off = 0;
 | |
| + 	for (i = 0; i < 256; i++) {
 | |
| +@@ -537,6 +541,9 @@ static unsigned char *find_token(unsigne
 | |
| + {
 | |
| + 	int i;
 | |
| + 
 | |
| ++	if (uncompressed)
 | |
| ++		return NULL;
 | |
| ++
 | |
| + 	for (i = 0; i < len - 1; i++) {
 | |
| + 		if (str[i] == token[0] && str[i+1] == token[1])
 | |
| + 			return &str[i];
 | |
| +@@ -609,6 +616,9 @@ static void optimize_result(void)
 | |
| + {
 | |
| + 	int i, best;
 | |
| + 
 | |
| ++	if (uncompressed)
 | |
| ++		return;
 | |
| ++
 | |
| + 	/* using the '\0' symbol last allows compress_symbols to use standard
 | |
| + 	 * fast string functions */
 | |
| + 	for (i = 255; i >= 0; i--) {
 | |
| +@@ -773,6 +783,8 @@ int main(int argc, char **argv)
 | |
| + 				absolute_percpu = 1;
 | |
| + 			else if (strcmp(argv[i], "--base-relative") == 0)
 | |
| + 				base_relative = 1;
 | |
| ++			else if (strcmp(argv[i], "--uncompressed") == 0)
 | |
| ++				uncompressed = 1;
 | |
| + 			else
 | |
| + 				usage();
 | |
| + 		}
 | |
| +--- a/scripts/link-vmlinux.sh
 | |
| ++++ b/scripts/link-vmlinux.sh
 | |
| +@@ -186,6 +186,10 @@ kallsyms()
 | |
| + 		kallsymopt="${kallsymopt} --base-relative"
 | |
| + 	fi
 | |
| + 
 | |
| ++	if [ -n "${CONFIG_KALLSYMS_UNCOMPRESSED}" ]; then
 | |
| ++		kallsymopt="${kallsymopt} --uncompressed"
 | |
| ++	fi
 | |
| ++
 | |
| + 	info KSYMS ${2}
 | |
| + 	${NM} -n ${1} | scripts/kallsyms ${kallsymopt} > ${2}
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/205-backtrace_module_info.patch b/target/linux/generic/pending-5.10/205-backtrace_module_info.patch
 | |
| new file mode 100644
 | |
| index 0000000000..5953214757
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/205-backtrace_module_info.patch
 | |
| @@ -0,0 +1,41 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: kernel: when KALLSYMS is disabled, print module address + size for matching backtrace entries
 | |
| +
 | |
| +[john@phrozen.org: felix will add this to his upstream queue]
 | |
| +
 | |
| +lede-commit 53827cdc824556cda910b23ce5030c363b8f1461
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + lib/vsprintf.c | 15 +++++++++++----
 | |
| + 1 file changed, 11 insertions(+), 4 deletions(-)
 | |
| +
 | |
| +--- a/lib/vsprintf.c
 | |
| ++++ b/lib/vsprintf.c
 | |
| +@@ -957,8 +957,10 @@ char *symbol_string(char *buf, char *end
 | |
| + 		    struct printf_spec spec, const char *fmt)
 | |
| + {
 | |
| + 	unsigned long value;
 | |
| +-#ifdef CONFIG_KALLSYMS
 | |
| + 	char sym[KSYM_SYMBOL_LEN];
 | |
| ++#ifndef CONFIG_KALLSYMS
 | |
| ++	struct module *mod;
 | |
| ++	int len;
 | |
| + #endif
 | |
| + 
 | |
| + 	if (fmt[1] == 'R')
 | |
| +@@ -975,8 +977,14 @@ char *symbol_string(char *buf, char *end
 | |
| + 
 | |
| + 	return string_nocheck(buf, end, sym, spec);
 | |
| + #else
 | |
| +-	return special_hex_number(buf, end, value, sizeof(void *));
 | |
| ++	len = snprintf(sym, sizeof(sym), "0x%lx", value);
 | |
| ++	mod = __module_address(value);
 | |
| ++	if (mod)
 | |
| ++		snprintf(sym + len, sizeof(sym) - len, " [%s@%p+0x%x]",
 | |
| ++			 mod->name, mod->core_layout.base,
 | |
| ++			 mod->core_layout.size);
 | |
| + #endif
 | |
| ++	return string(buf, end, sym, spec);
 | |
| + }
 | |
| + 
 | |
| + static const struct printf_spec default_str_spec = {
 | |
| diff --git a/target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch b/target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch
 | |
| new file mode 100644
 | |
| index 0000000000..29cfade716
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/240-remove-unsane-filenames-from-deps_initramfs-list.patch
 | |
| @@ -0,0 +1,30 @@
 | |
| +From: Gabor Juhos <juhosg@openwrt.org>
 | |
| +Subject: usr: sanitize deps_initramfs list
 | |
| +
 | |
| +If any filename in the intramfs dependency
 | |
| +list contains a colon, that causes a kernel
 | |
| +build error like this:
 | |
| +
 | |
| +/devel/openwrt/build_dir/linux-ar71xx_generic/linux-3.6.6/usr/Makefile:58: *** multiple target patterns.  Stop.
 | |
| +make[5]: *** [usr] Error 2
 | |
| +
 | |
| +Fix it by removing such filenames from the
 | |
| +deps_initramfs list.
 | |
| +
 | |
| +Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + usr/Makefile | 8 +++++---
 | |
| + 1 file changed, 5 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/usr/Makefile
 | |
| ++++ b/usr/Makefile
 | |
| +@@ -61,6 +61,8 @@ hostprogs := gen_init_cpio
 | |
| + # The dependency list is generated by gen_initramfs.sh -l
 | |
| + -include $(obj)/.initramfs_data.cpio.d
 | |
| + 
 | |
| ++deps_initramfs := $(foreach v,$(deps_initramfs),$(if $(findstring :,$(v)),,$(v)))
 | |
| ++
 | |
| + # do not try to update files included in initramfs
 | |
| + $(deps_initramfs): ;
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch b/target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch
 | |
| new file mode 100644
 | |
| index 0000000000..cd31f9d934
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/261-enable_wilink_platform_without_drivers.patch
 | |
| @@ -0,0 +1,20 @@
 | |
| +From: Imre Kaloz <kaloz@openwrt.org>
 | |
| +Subject: [PATCH] hack: net: wireless: make the wl12xx glue code available with
 | |
| + compat-wireless, too
 | |
| +
 | |
| +Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
 | |
| +---
 | |
| + drivers/net/wireless/ti/Kconfig | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/drivers/net/wireless/ti/Kconfig
 | |
| ++++ b/drivers/net/wireless/ti/Kconfig
 | |
| +@@ -20,7 +20,7 @@ source "drivers/net/wireless/ti/wlcore/K
 | |
| + 
 | |
| + config WILINK_PLATFORM_DATA
 | |
| + 	bool "TI WiLink platform data"
 | |
| +-	depends on WLCORE_SDIO || WL1251_SDIO
 | |
| ++	depends on WLCORE_SDIO || WL1251_SDIO || ARCH_OMAP2PLUS
 | |
| + 	default y
 | |
| + 	help
 | |
| + 	Small platform data bit needed to pass data to the sdio modules.
 | |
| diff --git a/target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch b/target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch
 | |
| new file mode 100644
 | |
| index 0000000000..df738ef97b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/270-platform-mikrotik-build-bits.patch
 | |
| @@ -0,0 +1,31 @@
 | |
| +From c2deb5ef01a0ef09088832744cbace9e239a6ee0 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
 | |
| +Date: Sat, 28 Mar 2020 12:11:50 +0100
 | |
| +Subject: [PATCH] generic: platform/mikrotik build bits (5.4)
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This patch adds platform/mikrotik kernel build bits
 | |
| +
 | |
| +Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
 | |
| +---
 | |
| + drivers/platform/Kconfig  | 2 ++
 | |
| + drivers/platform/Makefile | 1 +
 | |
| + 2 files changed, 3 insertions(+)
 | |
| +
 | |
| +--- a/drivers/platform/Kconfig
 | |
| ++++ b/drivers/platform/Kconfig
 | |
| +@@ -13,3 +13,5 @@ source "drivers/platform/chrome/Kconfig"
 | |
| + source "drivers/platform/mellanox/Kconfig"
 | |
| + 
 | |
| + source "drivers/platform/olpc/Kconfig"
 | |
| ++
 | |
| ++source "drivers/platform/mikrotik/Kconfig"
 | |
| +--- a/drivers/platform/Makefile
 | |
| ++++ b/drivers/platform/Makefile
 | |
| +@@ -9,3 +9,4 @@ obj-$(CONFIG_MIPS)		+= mips/
 | |
| + obj-$(CONFIG_OLPC_EC)		+= olpc/
 | |
| + obj-$(CONFIG_GOLDFISH)		+= goldfish/
 | |
| + obj-$(CONFIG_CHROME_PLATFORMS)	+= chrome/
 | |
| ++obj-$(CONFIG_MIKROTIK)		+= mikrotik/
 | |
| diff --git a/target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch b/target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a454733e66
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/300-mips_expose_boot_raw.patch
 | |
| @@ -0,0 +1,40 @@
 | |
| +From: Mark Miller <mark@mirell.org>
 | |
| +Subject: mips: expose CONFIG_BOOT_RAW
 | |
| +
 | |
| +This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on
 | |
| +certain Broadcom chipsets running CFE in order to load the kernel.
 | |
| +
 | |
| +Signed-off-by: Mark Miller <mark@mirell.org>
 | |
| +Acked-by: Rob Landley <rob@landley.net>
 | |
| +---
 | |
| +--- a/arch/mips/Kconfig
 | |
| ++++ b/arch/mips/Kconfig
 | |
| +@@ -1077,9 +1077,6 @@ config FW_ARC
 | |
| + config ARCH_MAY_HAVE_PC_FDC
 | |
| + 	bool
 | |
| + 
 | |
| +-config BOOT_RAW
 | |
| +-	bool
 | |
| +-
 | |
| + config CEVT_BCM1480
 | |
| + 	bool
 | |
| + 
 | |
| +@@ -3169,6 +3166,18 @@ choice
 | |
| + 		bool "Extend builtin kernel arguments with bootloader arguments"
 | |
| + endchoice
 | |
| + 
 | |
| ++config BOOT_RAW
 | |
| ++	bool "Enable the kernel to be executed from the load address"
 | |
| ++	default n
 | |
| ++	help
 | |
| ++	 Allow the kernel to be executed from the load address for
 | |
| ++	 bootloaders which cannot read the ELF format. This places
 | |
| ++	 a jump to start_kernel at the load address.
 | |
| ++
 | |
| ++	 If unsure, say N.
 | |
| ++
 | |
| ++
 | |
| ++
 | |
| + endmenu
 | |
| + 
 | |
| + config LOCKDEP_SUPPORT
 | |
| diff --git a/target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch b/target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch
 | |
| new file mode 100644
 | |
| index 0000000000..271923fca8
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/302-mips_no_branch_likely.patch
 | |
| @@ -0,0 +1,22 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: mips: use -mno-branch-likely for kernel and userspace
 | |
| +
 | |
| +saves ~11k kernel size after lzma and ~12k squashfs size in the
 | |
| +
 | |
| +lede-commit: 41a039f46450ffae9483d6216422098669da2900
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + arch/mips/Makefile | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/mips/Makefile
 | |
| ++++ b/arch/mips/Makefile
 | |
| +@@ -95,7 +95,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
 | |
| + # machines may also.  Since BFD is incredibly buggy with respect to
 | |
| + # crossformat linking we rely on the elf2ecoff tool for format conversion.
 | |
| + #
 | |
| +-cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
 | |
| ++cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
 | |
| + cflags-y			+= -msoft-float
 | |
| + LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
 | |
| + KBUILD_AFLAGS_MODULE		+= -mlong-calls
 | |
| diff --git a/target/linux/generic/pending-5.10/305-mips_module_reloc.patch b/target/linux/generic/pending-5.10/305-mips_module_reloc.patch
 | |
| new file mode 100644
 | |
| index 0000000000..839ba24293
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/305-mips_module_reloc.patch
 | |
| @@ -0,0 +1,371 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: mips: replace -mlong-calls with -mno-long-calls to make function calls faster in kernel modules to achieve this, try to
 | |
| +
 | |
| +lede-commit: 3b3d64743ba2a874df9d70cd19e242205b0a788c
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + arch/mips/Makefile             |   5 +
 | |
| + arch/mips/include/asm/module.h |   5 +
 | |
| + arch/mips/kernel/module.c      | 279 ++++++++++++++++++++++++++++++++++++++++-
 | |
| + 3 files changed, 284 insertions(+), 5 deletions(-)
 | |
| +
 | |
| +--- a/arch/mips/Makefile
 | |
| ++++ b/arch/mips/Makefile
 | |
| +@@ -98,8 +98,18 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
 | |
| + cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
 | |
| + cflags-y			+= -msoft-float
 | |
| + LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
 | |
| ++ifdef CONFIG_64BIT
 | |
| + KBUILD_AFLAGS_MODULE		+= -mlong-calls
 | |
| + KBUILD_CFLAGS_MODULE		+= -mlong-calls
 | |
| ++else
 | |
| ++  ifdef CONFIG_DYNAMIC_FTRACE
 | |
| ++    KBUILD_AFLAGS_MODULE	+= -mlong-calls
 | |
| ++    KBUILD_CFLAGS_MODULE	+= -mlong-calls
 | |
| ++  else
 | |
| ++    KBUILD_AFLAGS_MODULE	+= -mno-long-calls
 | |
| ++    KBUILD_CFLAGS_MODULE	+= -mno-long-calls
 | |
| ++  endif
 | |
| ++endif
 | |
| + 
 | |
| + ifeq ($(CONFIG_RELOCATABLE),y)
 | |
| + LDFLAGS_vmlinux			+= --emit-relocs
 | |
| +--- a/arch/mips/include/asm/module.h
 | |
| ++++ b/arch/mips/include/asm/module.h
 | |
| +@@ -12,6 +12,11 @@ struct mod_arch_specific {
 | |
| + 	const struct exception_table_entry *dbe_start;
 | |
| + 	const struct exception_table_entry *dbe_end;
 | |
| + 	struct mips_hi16 *r_mips_hi16_list;
 | |
| ++
 | |
| ++	void *phys_plt_tbl;
 | |
| ++	void *virt_plt_tbl;
 | |
| ++	unsigned int phys_plt_offset;
 | |
| ++	unsigned int virt_plt_offset;
 | |
| + };
 | |
| + 
 | |
| + typedef uint8_t Elf64_Byte;		/* Type for a 8-bit quantity.  */
 | |
| +--- a/arch/mips/kernel/module.c
 | |
| ++++ b/arch/mips/kernel/module.c
 | |
| +@@ -31,14 +31,221 @@ struct mips_hi16 {
 | |
| + static LIST_HEAD(dbe_list);
 | |
| + static DEFINE_SPINLOCK(dbe_lock);
 | |
| + 
 | |
| +-#ifdef MODULE_START
 | |
| ++/*
 | |
| ++ * Get the potential max trampolines size required of the init and
 | |
| ++ * non-init sections. Only used if we cannot find enough contiguous
 | |
| ++ * physically mapped memory to put the module into.
 | |
| ++ */
 | |
| ++static unsigned int
 | |
| ++get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
 | |
| ++             const char *secstrings, unsigned int symindex, bool is_init)
 | |
| ++{
 | |
| ++	unsigned long ret = 0;
 | |
| ++	unsigned int i, j;
 | |
| ++	Elf_Sym *syms;
 | |
| ++
 | |
| ++	/* Everything marked ALLOC (this includes the exported symbols) */
 | |
| ++	for (i = 1; i < hdr->e_shnum; ++i) {
 | |
| ++		unsigned int info = sechdrs[i].sh_info;
 | |
| ++
 | |
| ++		if (sechdrs[i].sh_type != SHT_REL
 | |
| ++		    && sechdrs[i].sh_type != SHT_RELA)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		/* Not a valid relocation section? */
 | |
| ++		if (info >= hdr->e_shnum)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		/* Don't bother with non-allocated sections */
 | |
| ++		if (!(sechdrs[info].sh_flags & SHF_ALLOC))
 | |
| ++			continue;
 | |
| ++
 | |
| ++		/* If it's called *.init*, and we're not init, we're
 | |
| ++                   not interested */
 | |
| ++		if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
 | |
| ++		    != is_init)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		syms = (Elf_Sym *) sechdrs[symindex].sh_addr;
 | |
| ++		if (sechdrs[i].sh_type == SHT_REL) {
 | |
| ++			Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr;
 | |
| ++			unsigned int size = sechdrs[i].sh_size / sizeof(*rel);
 | |
| ++
 | |
| ++			for (j = 0; j < size; ++j) {
 | |
| ++				Elf_Sym *sym;
 | |
| ++
 | |
| ++				if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26)
 | |
| ++					continue;
 | |
| ++
 | |
| ++				sym = syms + ELF_MIPS_R_SYM(rel[j]);
 | |
| ++				if (!is_init && sym->st_shndx != SHN_UNDEF)
 | |
| ++					continue;
 | |
| ++
 | |
| ++				ret += 4 * sizeof(int);
 | |
| ++			}
 | |
| ++		} else {
 | |
| ++			Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr;
 | |
| ++			unsigned int size = sechdrs[i].sh_size / sizeof(*rela);
 | |
| ++
 | |
| ++			for (j = 0; j < size; ++j) {
 | |
| ++				Elf_Sym *sym;
 | |
| ++
 | |
| ++				if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26)
 | |
| ++					continue;
 | |
| ++
 | |
| ++				sym = syms + ELF_MIPS_R_SYM(rela[j]);
 | |
| ++				if (!is_init && sym->st_shndx != SHN_UNDEF)
 | |
| ++					continue;
 | |
| ++
 | |
| ++				ret += 4 * sizeof(int);
 | |
| ++			}
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++#ifndef MODULE_START
 | |
| ++static void *alloc_phys(unsigned long size)
 | |
| ++{
 | |
| ++	unsigned order;
 | |
| ++	struct page *page;
 | |
| ++	struct page *p;
 | |
| ++
 | |
| ++	size = PAGE_ALIGN(size);
 | |
| ++	order = get_order(size);
 | |
| ++
 | |
| ++	page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN |
 | |
| ++			__GFP_THISNODE, order);
 | |
| ++	if (!page)
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	split_page(page, order);
 | |
| ++
 | |
| ++	/* mark all pages except for the last one */
 | |
| ++	for (p = page; p + 1 < page + (size >> PAGE_SHIFT); ++p)
 | |
| ++		set_bit(PG_owner_priv_1, &p->flags);
 | |
| ++
 | |
| ++	for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p)
 | |
| ++		__free_page(p);
 | |
| ++
 | |
| ++	return page_address(page);
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| ++static void free_phys(void *ptr)
 | |
| ++{
 | |
| ++	struct page *page;
 | |
| ++	bool free;
 | |
| ++
 | |
| ++	page = virt_to_page(ptr);
 | |
| ++	do {
 | |
| ++		free = test_and_clear_bit(PG_owner_priv_1, &page->flags);
 | |
| ++		__free_page(page);
 | |
| ++		page++;
 | |
| ++	} while (free);
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| + void *module_alloc(unsigned long size)
 | |
| + {
 | |
| ++#ifdef MODULE_START
 | |
| + 	return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
 | |
| + 				GFP_KERNEL, PAGE_KERNEL, 0, NUMA_NO_NODE,
 | |
| + 				__builtin_return_address(0));
 | |
| ++#else
 | |
| ++	void *ptr;
 | |
| ++
 | |
| ++	if (size == 0)
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	ptr = alloc_phys(size);
 | |
| ++
 | |
| ++	/* If we failed to allocate physically contiguous memory,
 | |
| ++	 * fall back to regular vmalloc. The module loader code will
 | |
| ++	 * create jump tables to handle long jumps */
 | |
| ++	if (!ptr)
 | |
| ++		return vmalloc(size);
 | |
| ++
 | |
| ++	return ptr;
 | |
| ++#endif
 | |
| + }
 | |
| ++
 | |
| ++static inline bool is_phys_addr(void *ptr)
 | |
| ++{
 | |
| ++#ifdef CONFIG_64BIT
 | |
| ++	return (KSEGX((unsigned long)ptr) == CKSEG0);
 | |
| ++#else
 | |
| ++	return (KSEGX(ptr) == KSEG0);
 | |
| + #endif
 | |
| ++}
 | |
| ++
 | |
| ++/* Free memory returned from module_alloc */
 | |
| ++void module_memfree(void *module_region)
 | |
| ++{
 | |
| ++	if (is_phys_addr(module_region))
 | |
| ++		free_phys(module_region);
 | |
| ++	else
 | |
| ++		vfree(module_region);
 | |
| ++}
 | |
| ++
 | |
| ++static void *__module_alloc(int size, bool phys)
 | |
| ++{
 | |
| ++	void *ptr;
 | |
| ++
 | |
| ++	if (phys)
 | |
| ++		ptr = kmalloc(size, GFP_KERNEL);
 | |
| ++	else
 | |
| ++		ptr = vmalloc(size);
 | |
| ++	return ptr;
 | |
| ++}
 | |
| ++
 | |
| ++static void __module_free(void *ptr)
 | |
| ++{
 | |
| ++	if (is_phys_addr(ptr))
 | |
| ++		kfree(ptr);
 | |
| ++	else
 | |
| ++		vfree(ptr);
 | |
| ++}
 | |
| ++
 | |
| ++int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
 | |
| ++			      char *secstrings, struct module *mod)
 | |
| ++{
 | |
| ++	unsigned int symindex = 0;
 | |
| ++	unsigned int core_size, init_size;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	mod->arch.phys_plt_offset = 0;
 | |
| ++	mod->arch.virt_plt_offset = 0;
 | |
| ++	mod->arch.phys_plt_tbl = NULL;
 | |
| ++	mod->arch.virt_plt_tbl = NULL;
 | |
| ++
 | |
| ++	if (IS_ENABLED(CONFIG_64BIT))
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	for (i = 1; i < hdr->e_shnum; i++)
 | |
| ++		if (sechdrs[i].sh_type == SHT_SYMTAB)
 | |
| ++			symindex = i;
 | |
| ++
 | |
| ++	core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false);
 | |
| ++	init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true);
 | |
| ++
 | |
| ++	if ((core_size + init_size) == 0)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1);
 | |
| ++	if (!mod->arch.phys_plt_tbl)
 | |
| ++		return -ENOMEM;
 | |
| ++
 | |
| ++	mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0);
 | |
| ++	if (!mod->arch.virt_plt_tbl) {
 | |
| ++		__module_free(mod->arch.phys_plt_tbl);
 | |
| ++		mod->arch.phys_plt_tbl = NULL;
 | |
| ++		return -ENOMEM;
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| + 
 | |
| + static int apply_r_mips_none(struct module *me, u32 *location,
 | |
| + 			     u32 base, Elf_Addr v, bool rela)
 | |
| +@@ -54,9 +261,40 @@ static int apply_r_mips_32(struct module
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| ++static Elf_Addr add_plt_entry_to(unsigned *plt_offset,
 | |
| ++				 void *start, Elf_Addr v)
 | |
| ++{
 | |
| ++	unsigned *tramp = start + *plt_offset;
 | |
| ++	*plt_offset += 4 * sizeof(int);
 | |
| ++
 | |
| ++	/* adjust carry for addiu */
 | |
| ++	if (v & 0x00008000)
 | |
| ++		v += 0x10000;
 | |
| ++
 | |
| ++	tramp[0] = 0x3c190000 | (v >> 16);      /* lui t9, hi16 */
 | |
| ++	tramp[1] = 0x27390000 | (v & 0xffff);   /* addiu t9, t9, lo16 */
 | |
| ++	tramp[2] = 0x03200008;                  /* jr t9 */
 | |
| ++	tramp[3] = 0x00000000;                  /* nop */
 | |
| ++
 | |
| ++	return (Elf_Addr) tramp;
 | |
| ++}
 | |
| ++
 | |
| ++static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v)
 | |
| ++{
 | |
| ++	if (is_phys_addr(location))
 | |
| ++		return add_plt_entry_to(&me->arch.phys_plt_offset,
 | |
| ++				me->arch.phys_plt_tbl, v);
 | |
| ++	else
 | |
| ++		return add_plt_entry_to(&me->arch.virt_plt_offset,
 | |
| ++				me->arch.virt_plt_tbl, v);
 | |
| ++
 | |
| ++}
 | |
| ++
 | |
| + static int apply_r_mips_26(struct module *me, u32 *location,
 | |
| + 			   u32 base, Elf_Addr v, bool rela)
 | |
| + {
 | |
| ++	u32 ofs = base & 0x03ffffff;
 | |
| ++
 | |
| + 	if (v % 4) {
 | |
| + 		pr_err("module %s: dangerous R_MIPS_26 relocation\n",
 | |
| + 		       me->name);
 | |
| +@@ -64,13 +302,17 @@ static int apply_r_mips_26(struct module
 | |
| + 	}
 | |
| + 
 | |
| + 	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
 | |
| +-		pr_err("module %s: relocation overflow\n",
 | |
| +-		       me->name);
 | |
| +-		return -ENOEXEC;
 | |
| ++		v = add_plt_entry(me, location, v + (ofs << 2));
 | |
| ++		if (!v) {
 | |
| ++			pr_err("module %s: relocation overflow\n",
 | |
| ++			       me->name);
 | |
| ++			return -ENOEXEC;
 | |
| ++		}
 | |
| ++		ofs = 0;
 | |
| + 	}
 | |
| + 
 | |
| + 	*location = (*location & ~0x03ffffff) |
 | |
| +-		    ((base + (v >> 2)) & 0x03ffffff);
 | |
| ++		    ((ofs + (v >> 2)) & 0x03ffffff);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -446,9 +688,36 @@ int module_finalize(const Elf_Ehdr *hdr,
 | |
| + 		list_add(&me->arch.dbe_list, &dbe_list);
 | |
| + 		spin_unlock_irq(&dbe_lock);
 | |
| + 	}
 | |
| ++
 | |
| ++	/* Get rid of the fixup trampoline if we're running the module
 | |
| ++	 * from physically mapped address space */
 | |
| ++	if (me->arch.phys_plt_offset == 0) {
 | |
| ++		__module_free(me->arch.phys_plt_tbl);
 | |
| ++		me->arch.phys_plt_tbl = NULL;
 | |
| ++	}
 | |
| ++	if (me->arch.virt_plt_offset == 0) {
 | |
| ++		__module_free(me->arch.virt_plt_tbl);
 | |
| ++		me->arch.virt_plt_tbl = NULL;
 | |
| ++	}
 | |
| ++
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| ++void module_arch_freeing_init(struct module *mod)
 | |
| ++{
 | |
| ++	if (mod->state == MODULE_STATE_LIVE)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (mod->arch.phys_plt_tbl) {
 | |
| ++		__module_free(mod->arch.phys_plt_tbl);
 | |
| ++		mod->arch.phys_plt_tbl = NULL;
 | |
| ++	}
 | |
| ++	if (mod->arch.virt_plt_tbl) {
 | |
| ++		__module_free(mod->arch.virt_plt_tbl);
 | |
| ++		mod->arch.virt_plt_tbl = NULL;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| + void module_arch_cleanup(struct module *mod)
 | |
| + {
 | |
| + 	spin_lock_irq(&dbe_lock);
 | |
| diff --git a/target/linux/generic/pending-5.10/307-mips_highmem_offset.patch b/target/linux/generic/pending-5.10/307-mips_highmem_offset.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e1ada22f34
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/307-mips_highmem_offset.patch
 | |
| @@ -0,0 +1,19 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: kernel: adjust mips highmem offset to avoid the need for -mlong-calls on systems with >256M RAM
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + arch/mips/include/asm/mach-generic/spaces.h | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/mips/include/asm/mach-generic/spaces.h
 | |
| ++++ b/arch/mips/include/asm/mach-generic/spaces.h
 | |
| +@@ -54,7 +54,7 @@
 | |
| +  * Memory above this physical address will be considered highmem.
 | |
| +  */
 | |
| + #ifndef HIGHMEM_START
 | |
| +-#define HIGHMEM_START		_AC(0x20000000, UL)
 | |
| ++#define HIGHMEM_START		_AC(0x10000000, UL)
 | |
| + #endif
 | |
| + 
 | |
| + #endif /* CONFIG_32BIT */
 | |
| diff --git a/target/linux/generic/pending-5.10/308-mips32r2_tune.patch b/target/linux/generic/pending-5.10/308-mips32r2_tune.patch
 | |
| new file mode 100644
 | |
| index 0000000000..bbea947382
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/308-mips32r2_tune.patch
 | |
| @@ -0,0 +1,22 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: kernel: add -mtune=34kc to MIPS CFLAGS when building for mips32r2
 | |
| +
 | |
| +This provides a good tradeoff across at least 24Kc-74Kc, while also
 | |
| +producing smaller code.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + arch/mips/Makefile | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/mips/Makefile
 | |
| ++++ b/arch/mips/Makefile
 | |
| +@@ -174,7 +174,7 @@ cflags-$(CONFIG_CPU_VR41XX)	+= -march=r4
 | |
| + cflags-$(CONFIG_CPU_R4X00)	+= -march=r4600 -Wa,--trap
 | |
| + cflags-$(CONFIG_CPU_TX49XX)	+= -march=r4600 -Wa,--trap
 | |
| + cflags-$(CONFIG_CPU_MIPS32_R1)	+= -march=mips32 -Wa,--trap
 | |
| +-cflags-$(CONFIG_CPU_MIPS32_R2)	+= -march=mips32r2 -Wa,--trap
 | |
| ++cflags-$(CONFIG_CPU_MIPS32_R2)	+= -march=mips32r2 -mtune=34kc -Wa,--trap
 | |
| + cflags-$(CONFIG_CPU_MIPS32_R5)	+= -march=mips32r5 -Wa,--trap -modd-spreg
 | |
| + cflags-$(CONFIG_CPU_MIPS32_R6)	+= -march=mips32r6 -Wa,--trap -modd-spreg
 | |
| + cflags-$(CONFIG_CPU_MIPS64_R1)	+= -march=mips64 -Wa,--trap
 | |
| diff --git a/target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch b/target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch
 | |
| new file mode 100644
 | |
| index 0000000000..794f027f18
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/309-MIPS-Add-CPU-option-reporting-to-proc-cpuinfo.patch
 | |
| @@ -0,0 +1,140 @@
 | |
| +From 87ec87c2ad615c1a177cd08ef5fa29fc739f6e50 Mon Sep 17 00:00:00 2001
 | |
| +From: Hauke Mehrtens <hauke@hauke-m.de>
 | |
| +Date: Sun, 23 Dec 2018 18:06:53 +0100
 | |
| +Subject: [PATCH] MIPS: Add CPU option reporting to /proc/cpuinfo
 | |
| +
 | |
| +Many MIPS CPUs have optional CPU features which are not activates for
 | |
| +all CPU cores. Print the CPU options which are implemented in the core
 | |
| +in /proc/cpuinfo. This makes it possible to see what features are
 | |
| +supported and which are not supported. This should cover all standard
 | |
| +MIPS extensions, before it only printed information about the main MIPS
 | |
| +ASEs.
 | |
| +
 | |
| +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
 | |
| +---
 | |
| + arch/mips/kernel/proc.c | 116 ++++++++++++++++++++++++++++++++++++++++
 | |
| + 1 file changed, 116 insertions(+)
 | |
| +
 | |
| +--- a/arch/mips/kernel/proc.c
 | |
| ++++ b/arch/mips/kernel/proc.c
 | |
| +@@ -138,6 +138,120 @@ static int show_cpuinfo(struct seq_file
 | |
| + 		seq_printf(m, "micromips kernel\t: %s\n",
 | |
| + 		      (read_c0_config3() & MIPS_CONF3_ISA_OE) ?  "yes" : "no");
 | |
| + 	}
 | |
| ++
 | |
| ++	seq_printf(m, "Options implemented\t:");
 | |
| ++	if (cpu_has_tlb)
 | |
| ++		seq_printf(m, "%s", " tlb");
 | |
| ++	if (cpu_has_ftlb)
 | |
| ++		seq_printf(m, "%s", " ftlb");
 | |
| ++	if (cpu_has_tlbinv)
 | |
| ++		seq_printf(m, "%s", " tlbinv");
 | |
| ++	if (cpu_has_segments)
 | |
| ++		seq_printf(m, "%s", " segments");
 | |
| ++	if (cpu_has_rixiex)
 | |
| ++		seq_printf(m, "%s", " rixiex");
 | |
| ++	if (cpu_has_ldpte)
 | |
| ++		seq_printf(m, "%s", " ldpte");
 | |
| ++	if (cpu_has_maar)
 | |
| ++		seq_printf(m, "%s", " maar");
 | |
| ++	if (cpu_has_rw_llb)
 | |
| ++		seq_printf(m, "%s", " rw_llb");
 | |
| ++	if (cpu_has_4kex)
 | |
| ++		seq_printf(m, "%s", " 4kex");
 | |
| ++	if (cpu_has_3k_cache)
 | |
| ++		seq_printf(m, "%s", " 3k_cache");
 | |
| ++	if (cpu_has_4k_cache)
 | |
| ++		seq_printf(m, "%s", " 4k_cache");
 | |
| ++	if (cpu_has_6k_cache)
 | |
| ++		seq_printf(m, "%s", " 6k_cache");
 | |
| ++	if (cpu_has_8k_cache)
 | |
| ++		seq_printf(m, "%s", " 8k_cache");
 | |
| ++	if (cpu_has_tx39_cache)
 | |
| ++		seq_printf(m, "%s", " tx39_cache");
 | |
| ++	if (cpu_has_octeon_cache)
 | |
| ++		seq_printf(m, "%s", " octeon_cache");
 | |
| ++	if (cpu_has_fpu)
 | |
| ++		seq_printf(m, "%s", " fpu");
 | |
| ++	if (cpu_has_32fpr)
 | |
| ++		seq_printf(m, "%s", " 32fpr");
 | |
| ++	if (cpu_has_cache_cdex_p)
 | |
| ++		seq_printf(m, "%s", " cache_cdex_p");
 | |
| ++	if (cpu_has_cache_cdex_s)
 | |
| ++		seq_printf(m, "%s", " cache_cdex_s");
 | |
| ++	if (cpu_has_prefetch)
 | |
| ++		seq_printf(m, "%s", " prefetch");
 | |
| ++	if (cpu_has_mcheck)
 | |
| ++		seq_printf(m, "%s", " mcheck");
 | |
| ++	if (cpu_has_ejtag)
 | |
| ++		seq_printf(m, "%s", " ejtag");
 | |
| ++	if (cpu_has_llsc)
 | |
| ++		seq_printf(m, "%s", " llsc");
 | |
| ++	if (cpu_has_guestctl0ext)
 | |
| ++		seq_printf(m, "%s", " guestctl0ext");
 | |
| ++	if (cpu_has_guestctl1)
 | |
| ++		seq_printf(m, "%s", " guestctl1");
 | |
| ++	if (cpu_has_guestctl2)
 | |
| ++		seq_printf(m, "%s", " guestctl2");
 | |
| ++	if (cpu_has_guestid)
 | |
| ++		seq_printf(m, "%s", " guestid");
 | |
| ++	if (cpu_has_drg)
 | |
| ++		seq_printf(m, "%s", " drg");
 | |
| ++	if (cpu_has_rixi)
 | |
| ++		seq_printf(m, "%s", " rixi");
 | |
| ++	if (cpu_has_lpa)
 | |
| ++		seq_printf(m, "%s", " lpa");
 | |
| ++	if (cpu_has_mvh)
 | |
| ++		seq_printf(m, "%s", " mvh");
 | |
| ++	if (cpu_has_vtag_icache)
 | |
| ++		seq_printf(m, "%s", " vtag_icache");
 | |
| ++	if (cpu_has_dc_aliases)
 | |
| ++		seq_printf(m, "%s", " dc_aliases");
 | |
| ++	if (cpu_has_ic_fills_f_dc)
 | |
| ++		seq_printf(m, "%s", " ic_fills_f_dc");
 | |
| ++	if (cpu_has_pindexed_dcache)
 | |
| ++		seq_printf(m, "%s", " pindexed_dcache");
 | |
| ++	if (cpu_has_userlocal)
 | |
| ++		seq_printf(m, "%s", " userlocal");
 | |
| ++	if (cpu_has_nofpuex)
 | |
| ++		seq_printf(m, "%s", " nofpuex");
 | |
| ++	if (cpu_has_vint)
 | |
| ++		seq_printf(m, "%s", " vint");
 | |
| ++	if (cpu_has_veic)
 | |
| ++		seq_printf(m, "%s", " veic");
 | |
| ++	if (cpu_has_inclusive_pcaches)
 | |
| ++		seq_printf(m, "%s", " inclusive_pcaches");
 | |
| ++	if (cpu_has_perf_cntr_intr_bit)
 | |
| ++		seq_printf(m, "%s", " perf_cntr_intr_bit");
 | |
| ++	if (cpu_has_ufr)
 | |
| ++		seq_printf(m, "%s", " ufr");
 | |
| ++	if (cpu_has_fre)
 | |
| ++		seq_printf(m, "%s", " fre");
 | |
| ++	if (cpu_has_cdmm)
 | |
| ++		seq_printf(m, "%s", " cdmm");
 | |
| ++	if (cpu_has_small_pages)
 | |
| ++		seq_printf(m, "%s", " small_pages");
 | |
| ++	if (cpu_has_nan_legacy)
 | |
| ++		seq_printf(m, "%s", " nan_legacy");
 | |
| ++	if (cpu_has_nan_2008)
 | |
| ++		seq_printf(m, "%s", " nan_2008");
 | |
| ++	if (cpu_has_ebase_wg)
 | |
| ++		seq_printf(m, "%s", " ebase_wg");
 | |
| ++	if (cpu_has_badinstr)
 | |
| ++		seq_printf(m, "%s", " badinstr");
 | |
| ++	if (cpu_has_badinstrp)
 | |
| ++		seq_printf(m, "%s", " badinstrp");
 | |
| ++	if (cpu_has_contextconfig)
 | |
| ++		seq_printf(m, "%s", " contextconfig");
 | |
| ++	if (cpu_has_perf)
 | |
| ++		seq_printf(m, "%s", " perf");
 | |
| ++	if (cpu_has_shared_ftlb_ram)
 | |
| ++		seq_printf(m, "%s", " shared_ftlb_ram");
 | |
| ++	if (cpu_has_shared_ftlb_entries)
 | |
| ++		seq_printf(m, "%s", " shared_ftlb_entries");
 | |
| ++	if (cpu_has_mipsmt_pertccounters)
 | |
| ++		seq_printf(m, "%s", " mipsmt_pertccounters");
 | |
| ++	seq_printf(m, "\n");
 | |
| ++
 | |
| + 	seq_printf(m, "shadow register sets\t: %d\n",
 | |
| + 		      cpu_data[n].srsets);
 | |
| + 	seq_printf(m, "kscratch registers\t: %d\n",
 | |
| diff --git a/target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch
 | |
| new file mode 100644
 | |
| index 0000000000..191dc6ac3c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/310-arm_module_unresolved_weak_sym.patch
 | |
| @@ -0,0 +1,22 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: fix errors in unresolved weak symbols on arm
 | |
| +
 | |
| +lede-commit: 570699d4838a907c3ef9f2819bf19eb72997b32f
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + arch/arm/kernel/module.c | 4 ++++
 | |
| + 1 file changed, 4 insertions(+)
 | |
| +
 | |
| +--- a/arch/arm/kernel/module.c
 | |
| ++++ b/arch/arm/kernel/module.c
 | |
| +@@ -105,6 +105,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
 | |
| + 			return -ENOEXEC;
 | |
| + 		}
 | |
| + 
 | |
| ++		if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) &&
 | |
| ++		    ELF_ST_BIND(sym->st_info) == STB_WEAK)
 | |
| ++			continue;
 | |
| ++
 | |
| + 		loc = dstsec->sh_addr + rel->r_offset;
 | |
| + 
 | |
| + 		switch (ELF32_R_TYPE(rel->r_info)) {
 | |
| diff --git a/target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch b/target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch
 | |
| new file mode 100644
 | |
| index 0000000000..3f8808f702
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/311-MIPS-zboot-put-appended-dtb-into-a-section.patch
 | |
| @@ -0,0 +1,36 @@
 | |
| +From 7d1531c81c0fb4c93bea8dc316043ad0e4d0c270 Mon Sep 17 00:00:00 2001
 | |
| +From: Chuanhong Guo <gch981213@gmail.com>
 | |
| +Date: Sun, 25 Oct 2020 23:19:40 +0800
 | |
| +Subject: [PATCH] MIPS: zboot: put appended dtb into a section
 | |
| +
 | |
| +This will make a separated section for dtb appear in ELF, and we can
 | |
| +then use objcopy to patch a dtb into vmlinuz when RAW_APPENDED_DTB
 | |
| +is set in kernel config.
 | |
| +
 | |
| +command to patch a dtb:
 | |
| +objcopy --set-section-flags=.appended_dtb=alloc,contents \
 | |
| +        --update-section=.appended_dtb=<target>.dtb vmlinuz vmlinuz-dtb
 | |
| +
 | |
| +Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
 | |
| +---
 | |
| + arch/mips/boot/compressed/ld.script | 9 ++++++---
 | |
| + 1 file changed, 6 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/arch/mips/boot/compressed/ld.script
 | |
| ++++ b/arch/mips/boot/compressed/ld.script
 | |
| +@@ -31,9 +31,12 @@ SECTIONS
 | |
| + 		CONSTRUCTORS
 | |
| + 		. = ALIGN(16);
 | |
| + 	}
 | |
| +-	__appended_dtb = .;
 | |
| +-	/* leave space for appended DTB */
 | |
| +-	. += 0x100000;
 | |
| ++
 | |
| ++	.appended_dtb : {
 | |
| ++		__appended_dtb = .;
 | |
| ++		/* leave space for appended DTB */
 | |
| ++		. += 0x100000;
 | |
| ++	}
 | |
| + 
 | |
| + 	_edata = .;
 | |
| + 	/* End of data section */
 | |
| diff --git a/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch b/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2808c95322
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/330-MIPS-kexec-Accept-command-line-parameters-from-users.patch
 | |
| @@ -0,0 +1,281 @@
 | |
| +From: Yousong Zhou <yszhou4tech@gmail.com>
 | |
| +Subject: MIPS: kexec: Accept command line parameters from userspace.
 | |
| +
 | |
| +Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
 | |
| +---
 | |
| + arch/mips/kernel/machine_kexec.c   |  153 +++++++++++++++++++++++++++++++-----
 | |
| + arch/mips/kernel/machine_kexec.h   |   20 +++++
 | |
| + arch/mips/kernel/relocate_kernel.S |   21 +++--
 | |
| + 3 files changed, 167 insertions(+), 27 deletions(-)
 | |
| + create mode 100644 arch/mips/kernel/machine_kexec.h
 | |
| +
 | |
| +--- a/arch/mips/kernel/machine_kexec.c
 | |
| ++++ b/arch/mips/kernel/machine_kexec.c
 | |
| +@@ -9,14 +9,11 @@
 | |
| + #include <linux/delay.h>
 | |
| + #include <linux/libfdt.h>
 | |
| + 
 | |
| ++#include <asm/bootinfo.h>
 | |
| + #include <asm/cacheflush.h>
 | |
| + #include <asm/page.h>
 | |
| +-
 | |
| +-extern const unsigned char relocate_new_kernel[];
 | |
| +-extern const size_t relocate_new_kernel_size;
 | |
| +-
 | |
| +-extern unsigned long kexec_start_address;
 | |
| +-extern unsigned long kexec_indirection_page;
 | |
| ++#include <linux/uaccess.h>
 | |
| ++#include "machine_kexec.h"
 | |
| + 
 | |
| + static unsigned long reboot_code_buffer;
 | |
| + 
 | |
| +@@ -30,6 +27,101 @@ void (*_crash_smp_send_stop)(void) = NUL
 | |
| + void (*_machine_kexec_shutdown)(void) = NULL;
 | |
| + void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
 | |
| + 
 | |
| ++static void machine_kexec_print_args(void)
 | |
| ++{
 | |
| ++	unsigned long argc = (int)kexec_args[0];
 | |
| ++	int i;
 | |
| ++
 | |
| ++	pr_info("kexec_args[0] (argc): %lu\n", argc);
 | |
| ++	pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
 | |
| ++	pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
 | |
| ++	pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
 | |
| ++
 | |
| ++	for (i = 0; i < argc; i++) {
 | |
| ++		pr_info("kexec_argv[%d] = %p, %s\n",
 | |
| ++				i, kexec_argv[i], kexec_argv[i]);
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++static void machine_kexec_init_argv(struct kimage *image)
 | |
| ++{
 | |
| ++	void __user *buf = NULL;
 | |
| ++	size_t bufsz;
 | |
| ++	size_t size;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	bufsz = 0;
 | |
| ++	for (i = 0; i < image->nr_segments; i++) {
 | |
| ++		struct kexec_segment *seg;
 | |
| ++
 | |
| ++		seg = &image->segment[i];
 | |
| ++		if (seg->bufsz < 6)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		if (strncmp((char *) seg->buf, "kexec ", 6))
 | |
| ++			continue;
 | |
| ++
 | |
| ++		buf = seg->buf;
 | |
| ++		bufsz = seg->bufsz;
 | |
| ++		break;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (!buf)
 | |
| ++		return;
 | |
| ++
 | |
| ++	size = KEXEC_COMMAND_LINE_SIZE;
 | |
| ++	size = min(size, bufsz);
 | |
| ++	if (size < bufsz)
 | |
| ++		pr_warn("kexec command line truncated to %zd bytes\n", size);
 | |
| ++
 | |
| ++	/* Copy to kernel space */
 | |
| ++	if (copy_from_user(kexec_argv_buf, buf, size))
 | |
| ++		pr_warn("kexec command line copy to kernel space failed\n");
 | |
| ++
 | |
| ++	kexec_argv_buf[size - 1] = 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void machine_kexec_parse_argv(struct kimage *image)
 | |
| ++{
 | |
| ++	char *reboot_code_buffer;
 | |
| ++	int reloc_delta;
 | |
| ++	char *ptr;
 | |
| ++	int argc;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	ptr = kexec_argv_buf;
 | |
| ++	argc = 0;
 | |
| ++
 | |
| ++	/*
 | |
| ++	 * convert command line string to array of parameters
 | |
| ++	 * (as bootloader does).
 | |
| ++	 */
 | |
| ++	while (ptr && *ptr && (KEXEC_MAX_ARGC > argc)) {
 | |
| ++		if (*ptr == ' ') {
 | |
| ++			*ptr++ = '\0';
 | |
| ++			continue;
 | |
| ++		}
 | |
| ++
 | |
| ++		kexec_argv[argc++] = ptr;
 | |
| ++		ptr = strchr(ptr, ' ');
 | |
| ++	}
 | |
| ++
 | |
| ++	if (!argc)
 | |
| ++		return;
 | |
| ++
 | |
| ++	kexec_args[0] = argc;
 | |
| ++	kexec_args[1] = (unsigned long)kexec_argv;
 | |
| ++	kexec_args[2] = 0;
 | |
| ++	kexec_args[3] = 0;
 | |
| ++
 | |
| ++	reboot_code_buffer = page_address(image->control_code_page);
 | |
| ++	reloc_delta = reboot_code_buffer - (char *)kexec_relocate_new_kernel;
 | |
| ++
 | |
| ++	kexec_args[1] += reloc_delta;
 | |
| ++	for (i = 0; i < argc; i++)
 | |
| ++		kexec_argv[i] += reloc_delta;
 | |
| ++}
 | |
| ++
 | |
| + static void kexec_image_info(const struct kimage *kimage)
 | |
| + {
 | |
| + 	unsigned long i;
 | |
| +@@ -99,6 +191,18 @@ machine_kexec_prepare(struct kimage *kim
 | |
| + #endif
 | |
| + 
 | |
| + 	kexec_image_info(kimage);
 | |
| ++	/*
 | |
| ++	 * Whenever arguments passed from kexec-tools, Init the arguments as
 | |
| ++	 * the original ones to try avoiding booting failure.
 | |
| ++	 */
 | |
| ++
 | |
| ++	kexec_args[0] = fw_arg0;
 | |
| ++	kexec_args[1] = fw_arg1;
 | |
| ++	kexec_args[2] = fw_arg2;
 | |
| ++	kexec_args[3] = fw_arg3;
 | |
| ++
 | |
| ++	machine_kexec_init_argv(kimage);
 | |
| ++	machine_kexec_parse_argv(kimage);
 | |
| + 
 | |
| + 	if (_machine_kexec_prepare)
 | |
| + 		return _machine_kexec_prepare(kimage);
 | |
| +@@ -161,7 +265,7 @@ machine_crash_shutdown(struct pt_regs *r
 | |
| + void kexec_nonboot_cpu_jump(void)
 | |
| + {
 | |
| + 	local_flush_icache_range((unsigned long)relocated_kexec_smp_wait,
 | |
| +-				 reboot_code_buffer + relocate_new_kernel_size);
 | |
| ++				 reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
 | |
| + 
 | |
| + 	relocated_kexec_smp_wait(NULL);
 | |
| + }
 | |
| +@@ -199,7 +303,7 @@ void kexec_reboot(void)
 | |
| + 	 * machine_kexec() CPU.
 | |
| + 	 */
 | |
| + 	local_flush_icache_range(reboot_code_buffer,
 | |
| +-				 reboot_code_buffer + relocate_new_kernel_size);
 | |
| ++				 reboot_code_buffer + KEXEC_RELOCATE_NEW_KERNEL_SIZE);
 | |
| + 
 | |
| + 	do_kexec = (void *)reboot_code_buffer;
 | |
| + 	do_kexec();
 | |
| +@@ -212,10 +316,12 @@ machine_kexec(struct kimage *image)
 | |
| + 	unsigned long *ptr;
 | |
| + 
 | |
| + 	reboot_code_buffer =
 | |
| +-	  (unsigned long)page_address(image->control_code_page);
 | |
| ++		(unsigned long)page_address(image->control_code_page);
 | |
| ++	pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer);
 | |
| + 
 | |
| + 	kexec_start_address =
 | |
| + 		(unsigned long) phys_to_virt(image->start);
 | |
| ++	pr_info("kexec_start_address = %p\n", (void *)kexec_start_address);
 | |
| + 
 | |
| + 	if (image->type == KEXEC_TYPE_DEFAULT) {
 | |
| + 		kexec_indirection_page =
 | |
| +@@ -223,9 +329,19 @@ machine_kexec(struct kimage *image)
 | |
| + 	} else {
 | |
| + 		kexec_indirection_page = (unsigned long)&image->head;
 | |
| + 	}
 | |
| ++	pr_info("kexec_indirection_page = %p\n", (void *)kexec_indirection_page);
 | |
| + 
 | |
| +-	memcpy((void*)reboot_code_buffer, relocate_new_kernel,
 | |
| +-	       relocate_new_kernel_size);
 | |
| ++	pr_info("Where is memcpy: %p\n", memcpy);
 | |
| ++	pr_info("kexec_relocate_new_kernel = %p, kexec_relocate_new_kernel_end = %p\n",
 | |
| ++		(void *)kexec_relocate_new_kernel, &kexec_relocate_new_kernel_end);
 | |
| ++	pr_info("Copy %lu bytes from %p to %p\n", KEXEC_RELOCATE_NEW_KERNEL_SIZE,
 | |
| ++		(void *)kexec_relocate_new_kernel, (void *)reboot_code_buffer);
 | |
| ++	memcpy((void*)reboot_code_buffer, kexec_relocate_new_kernel,
 | |
| ++	       KEXEC_RELOCATE_NEW_KERNEL_SIZE);
 | |
| ++
 | |
| ++	pr_info("Before _print_args().\n");
 | |
| ++	machine_kexec_print_args();
 | |
| ++	pr_info("Before eval loop.\n");
 | |
| + 
 | |
| + 	/*
 | |
| + 	 * The generic kexec code builds a page list with physical
 | |
| +@@ -256,7 +372,7 @@ machine_kexec(struct kimage *image)
 | |
| + #ifdef CONFIG_SMP
 | |
| + 	/* All secondary cpus now may jump to kexec_wait cycle */
 | |
| + 	relocated_kexec_smp_wait = reboot_code_buffer +
 | |
| +-		(void *)(kexec_smp_wait - relocate_new_kernel);
 | |
| ++		(void *)(kexec_smp_wait - kexec_relocate_new_kernel);
 | |
| + 	smp_wmb();
 | |
| + 	atomic_set(&kexec_ready_to_reboot, 1);
 | |
| + #endif
 | |
| +--- /dev/null
 | |
| ++++ b/arch/mips/kernel/machine_kexec.h
 | |
| +@@ -0,0 +1,20 @@
 | |
| ++#ifndef _MACHINE_KEXEC_H
 | |
| ++#define _MACHINE_KEXEC_H
 | |
| ++
 | |
| ++#ifndef __ASSEMBLY__
 | |
| ++extern const unsigned char kexec_relocate_new_kernel[];
 | |
| ++extern unsigned long kexec_relocate_new_kernel_end;
 | |
| ++extern unsigned long kexec_start_address;
 | |
| ++extern unsigned long kexec_indirection_page;
 | |
| ++
 | |
| ++extern char kexec_argv_buf[];
 | |
| ++extern char *kexec_argv[];
 | |
| ++
 | |
| ++#define KEXEC_RELOCATE_NEW_KERNEL_SIZE	((unsigned long)&kexec_relocate_new_kernel_end - (unsigned long)kexec_relocate_new_kernel)
 | |
| ++#endif /* !__ASSEMBLY__ */
 | |
| ++
 | |
| ++#define KEXEC_COMMAND_LINE_SIZE		256
 | |
| ++#define KEXEC_ARGV_SIZE			(KEXEC_COMMAND_LINE_SIZE / 16)
 | |
| ++#define KEXEC_MAX_ARGC			(KEXEC_ARGV_SIZE / sizeof(long))
 | |
| ++
 | |
| ++#endif
 | |
| +--- a/arch/mips/kernel/relocate_kernel.S
 | |
| ++++ b/arch/mips/kernel/relocate_kernel.S
 | |
| +@@ -10,8 +10,9 @@
 | |
| + #include <asm/mipsregs.h>
 | |
| + #include <asm/stackframe.h>
 | |
| + #include <asm/addrspace.h>
 | |
| ++#include "machine_kexec.h"
 | |
| + 
 | |
| +-LEAF(relocate_new_kernel)
 | |
| ++LEAF(kexec_relocate_new_kernel)
 | |
| + 	PTR_L a0,	arg0
 | |
| + 	PTR_L a1,	arg1
 | |
| + 	PTR_L a2,	arg2
 | |
| +@@ -96,7 +97,7 @@ done:
 | |
| + #endif
 | |
| + 	/* jump to kexec_start_address */
 | |
| + 	j		s1
 | |
| +-	END(relocate_new_kernel)
 | |
| ++	END(kexec_relocate_new_kernel)
 | |
| + 
 | |
| + #ifdef CONFIG_SMP
 | |
| + /*
 | |
| +@@ -182,9 +183,15 @@ kexec_indirection_page:
 | |
| + 	PTR		0
 | |
| + 	.size		kexec_indirection_page, PTRSIZE
 | |
| + 
 | |
| +-relocate_new_kernel_end:
 | |
| ++kexec_argv_buf:
 | |
| ++	EXPORT(kexec_argv_buf)
 | |
| ++	.skip		KEXEC_COMMAND_LINE_SIZE
 | |
| ++	.size		kexec_argv_buf, KEXEC_COMMAND_LINE_SIZE
 | |
| ++
 | |
| ++kexec_argv:
 | |
| ++	EXPORT(kexec_argv)
 | |
| ++	.skip		KEXEC_ARGV_SIZE
 | |
| ++	.size		kexec_argv, KEXEC_ARGV_SIZE
 | |
| + 
 | |
| +-relocate_new_kernel_size:
 | |
| +-	EXPORT(relocate_new_kernel_size)
 | |
| +-	PTR		relocate_new_kernel_end - relocate_new_kernel
 | |
| +-	.size		relocate_new_kernel_size, PTRSIZE
 | |
| ++kexec_relocate_new_kernel_end:
 | |
| ++	EXPORT(kexec_relocate_new_kernel_end)
 | |
| diff --git a/target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch b/target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch
 | |
| new file mode 100644
 | |
| index 0000000000..30158cf399
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/332-arc-add-OWRTDTB-section.patch
 | |
| @@ -0,0 +1,84 @@
 | |
| +From bb0c3b0175240bf152fd7c644821a0cf9f77c37c Mon Sep 17 00:00:00 2001
 | |
| +From: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
 | |
| +Date: Fri, 15 Mar 2019 18:53:38 +0300
 | |
| +Subject: [PATCH] arc add OWRTDTB section
 | |
| +
 | |
| +This change allows OpenWRT to patch resulting kernel binary with
 | |
| +external .dtb.
 | |
| +
 | |
| +That allows us to re-use exactky the same vmlinux on different boards
 | |
| +given its ARC core configurations match (at least cache line sizes etc).
 | |
| +
 | |
| +""patch-dtb" searches for ASCII "OWRTDTB:" strign and copies external
 | |
| +.dtb right after it, keeping the string in place.
 | |
| +
 | |
| +Signed-off-by: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
 | |
| +Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
 | |
| +Signed-off-by: Evgeniy Didin <Evgeniy.Didin@synopsys.com>
 | |
| +---
 | |
| + arch/arc/kernel/head.S        | 10 ++++++++++
 | |
| + arch/arc/kernel/setup.c       |  4 +++-
 | |
| + arch/arc/kernel/vmlinux.lds.S | 13 +++++++++++++
 | |
| + 3 files changed, 26 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/arc/kernel/head.S
 | |
| ++++ b/arch/arc/kernel/head.S
 | |
| +@@ -88,6 +88,16 @@
 | |
| + 	DSP_EARLY_INIT
 | |
| + .endm
 | |
| + 
 | |
| ++	; Here "patch-dtb" will embed external .dtb
 | |
| ++	; Note "patch-dtb" searches for ASCII "OWRTDTB:" string
 | |
| ++	; and pastes .dtb right after it, hense the string precedes
 | |
| ++	; __image_dtb symbol.
 | |
| ++	.section .owrt, "aw",@progbits
 | |
| ++	.ascii  "OWRTDTB:"
 | |
| ++ENTRY(__image_dtb)
 | |
| ++	.fill   0x4000
 | |
| ++END(__image_dtb)
 | |
| ++
 | |
| + 	.section .init.text, "ax",@progbits
 | |
| + 
 | |
| + ;----------------------------------------------------------------
 | |
| +--- a/arch/arc/kernel/setup.c
 | |
| ++++ b/arch/arc/kernel/setup.c
 | |
| +@@ -495,6 +495,8 @@ static inline bool uboot_arg_invalid(uns
 | |
| + /* We always pass 0 as magic from U-boot */
 | |
| + #define UBOOT_MAGIC_VALUE	0
 | |
| + 
 | |
| ++extern struct boot_param_header __image_dtb;
 | |
| ++
 | |
| + void __init handle_uboot_args(void)
 | |
| + {
 | |
| + 	bool use_embedded_dtb = true;
 | |
| +@@ -533,7 +535,7 @@ void __init handle_uboot_args(void)
 | |
| + ignore_uboot_args:
 | |
| + 
 | |
| + 	if (use_embedded_dtb) {
 | |
| +-		machine_desc = setup_machine_fdt(__dtb_start);
 | |
| ++		machine_desc = setup_machine_fdt(&__image_dtb);
 | |
| + 		if (!machine_desc)
 | |
| + 			panic("Embedded DT invalid\n");
 | |
| + 	}
 | |
| +--- a/arch/arc/kernel/vmlinux.lds.S
 | |
| ++++ b/arch/arc/kernel/vmlinux.lds.S
 | |
| +@@ -27,6 +27,19 @@ SECTIONS
 | |
| + 
 | |
| + 	. = CONFIG_LINUX_LINK_BASE;
 | |
| + 
 | |
| ++	/*
 | |
| ++	* In OpenWRT we want to patch built binary embedding .dtb of choice.
 | |
| ++	* This is implemented with "patch-dtb" utility which searches for
 | |
| ++	* "OWRTDTB:" string in first 16k of image and if it is found
 | |
| ++	* copies .dtb right after mentioned string.
 | |
| ++	*
 | |
| ++	* Note: "OWRTDTB:" won't be overwritten with .dtb, .dtb will follow it.
 | |
| ++	*/
 | |
| ++ 	.owrt : {
 | |
| ++		*(.owrt)
 | |
| ++	. = ALIGN(PAGE_SIZE);
 | |
| ++	}
 | |
| ++
 | |
| + 	_int_vec_base_lds = .;
 | |
| + 	.vector : {
 | |
| + 		*(.vector)
 | |
| diff --git a/target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch b/target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1848a84cc4
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/333-arc-enable-unaligned-access-in-kernel-mode.patch
 | |
| @@ -0,0 +1,24 @@
 | |
| +From: Alexey Brodkin <abrodkin@synopsys.com>
 | |
| +Subject: arc: enable unaligned access in kernel mode
 | |
| +
 | |
| +This enables misaligned access handling even in kernel mode.
 | |
| +Some wireless drivers (ath9k-htc and mt7601u) use misaligned accesses
 | |
| +here and there and to cope with that without fixing stuff in the drivers
 | |
| +we're just gracefully handling it on ARC.
 | |
| +
 | |
| +Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
 | |
| +---
 | |
| + arch/arc/kernel/unaligned.c | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/arc/kernel/unaligned.c
 | |
| ++++ b/arch/arc/kernel/unaligned.c
 | |
| +@@ -202,7 +202,7 @@ int misaligned_fixup(unsigned long addre
 | |
| + 	char buf[TASK_COMM_LEN];
 | |
| + 
 | |
| + 	/* handle user mode only and only if enabled by sysadmin */
 | |
| +-	if (!user_mode(regs) || !unaligned_enabled)
 | |
| ++	if (!unaligned_enabled)
 | |
| + 		return 1;
 | |
| + 
 | |
| + 	if (no_unaligned_warning) {
 | |
| diff --git a/target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch b/target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch
 | |
| new file mode 100644
 | |
| index 0000000000..6792a66f8a
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/342-powerpc-Enable-kernel-XZ-compression-option-on-PPC_8.patch
 | |
| @@ -0,0 +1,25 @@
 | |
| +From 66770a004afe10df11d3902e16eaa0c2c39436bb Mon Sep 17 00:00:00 2001
 | |
| +From: Pawel Dembicki <paweldembicki@gmail.com>
 | |
| +Date: Fri, 24 May 2019 17:56:19 +0200
 | |
| +Subject: [PATCH] powerpc: Enable kernel XZ compression option on PPC_85xx
 | |
| +
 | |
| +Enable kernel XZ compression option on PPC_85xx. Tested with
 | |
| +simpleImage on TP-Link TL-WDR4900 (Freescale P1014 processor).
 | |
| +
 | |
| +Suggested-by: Christian Lamparter <chunkeey@gmail.com>
 | |
| +Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
 | |
| +---
 | |
| + arch/powerpc/Kconfig | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/arch/powerpc/Kconfig
 | |
| ++++ b/arch/powerpc/Kconfig
 | |
| +@@ -214,7 +214,7 @@ config PPC
 | |
| + 	select HAVE_KERNEL_GZIP
 | |
| + 	select HAVE_KERNEL_LZMA			if DEFAULT_UIMAGE
 | |
| + 	select HAVE_KERNEL_LZO			if DEFAULT_UIMAGE
 | |
| +-	select HAVE_KERNEL_XZ			if PPC_BOOK3S || 44x
 | |
| ++	select HAVE_KERNEL_XZ			if PPC_BOOK3S || 44x || PPC_85xx
 | |
| + 	select HAVE_KPROBES
 | |
| + 	select HAVE_KPROBES_ON_FTRACE
 | |
| + 	select HAVE_KRETPROBES
 | |
| diff --git a/target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch b/target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..6f816a6ad3
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/400-mtd-mtdsplit-support.patch
 | |
| @@ -0,0 +1,313 @@
 | |
| +--- a/drivers/mtd/Kconfig
 | |
| ++++ b/drivers/mtd/Kconfig
 | |
| +@@ -12,6 +12,25 @@ menuconfig MTD
 | |
| + 
 | |
| + if MTD
 | |
| + 
 | |
| ++menu "OpenWrt specific MTD options"
 | |
| ++
 | |
| ++config MTD_ROOTFS_ROOT_DEV
 | |
| ++	bool "Automatically set 'rootfs' partition to be root filesystem"
 | |
| ++	default y
 | |
| ++
 | |
| ++config MTD_SPLIT_FIRMWARE
 | |
| ++	bool "Automatically split firmware partition for kernel+rootfs"
 | |
| ++	default y
 | |
| ++
 | |
| ++config MTD_SPLIT_FIRMWARE_NAME
 | |
| ++	string "Firmware partition name"
 | |
| ++	depends on MTD_SPLIT_FIRMWARE
 | |
| ++	default "firmware"
 | |
| ++
 | |
| ++source "drivers/mtd/mtdsplit/Kconfig"
 | |
| ++
 | |
| ++endmenu
 | |
| ++
 | |
| + config MTD_TESTS
 | |
| + 	tristate "MTD tests support (DANGEROUS)"
 | |
| + 	depends on m
 | |
| +--- a/drivers/mtd/mtdpart.c
 | |
| ++++ b/drivers/mtd/mtdpart.c
 | |
| +@@ -15,10 +15,12 @@
 | |
| + #include <linux/kmod.h>
 | |
| + #include <linux/mtd/mtd.h>
 | |
| + #include <linux/mtd/partitions.h>
 | |
| ++#include <linux/magic.h>
 | |
| + #include <linux/err.h>
 | |
| + #include <linux/of.h>
 | |
| + 
 | |
| + #include "mtdcore.h"
 | |
| ++#include "mtdsplit/mtdsplit.h"
 | |
| + 
 | |
| + /*
 | |
| +  * MTD methods which simply translate the effective address and pass through
 | |
| +@@ -236,6 +238,146 @@ static int mtd_add_partition_attrs(struc
 | |
| + 	return ret;
 | |
| + }
 | |
| + 
 | |
| ++static DEFINE_SPINLOCK(part_parser_lock);
 | |
| ++static LIST_HEAD(part_parsers);
 | |
| ++
 | |
| ++static struct mtd_part_parser *mtd_part_parser_get(const char *name)
 | |
| ++{
 | |
| ++	struct mtd_part_parser *p, *ret = NULL;
 | |
| ++
 | |
| ++	spin_lock(&part_parser_lock);
 | |
| ++
 | |
| ++	list_for_each_entry(p, &part_parsers, list)
 | |
| ++		if (!strcmp(p->name, name) && try_module_get(p->owner)) {
 | |
| ++			ret = p;
 | |
| ++			break;
 | |
| ++		}
 | |
| ++
 | |
| ++	spin_unlock(&part_parser_lock);
 | |
| ++
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
 | |
| ++{
 | |
| ++	module_put(p->owner);
 | |
| ++}
 | |
| ++
 | |
| ++static struct mtd_part_parser *
 | |
| ++get_partition_parser_by_type(enum mtd_parser_type type,
 | |
| ++			     struct mtd_part_parser *start)
 | |
| ++{
 | |
| ++	struct mtd_part_parser *p, *ret = NULL;
 | |
| ++
 | |
| ++	spin_lock(&part_parser_lock);
 | |
| ++
 | |
| ++	p = list_prepare_entry(start, &part_parsers, list);
 | |
| ++	if (start)
 | |
| ++		mtd_part_parser_put(start);
 | |
| ++
 | |
| ++	list_for_each_entry_continue(p, &part_parsers, list) {
 | |
| ++		if (p->type == type && try_module_get(p->owner)) {
 | |
| ++			ret = p;
 | |
| ++			break;
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	spin_unlock(&part_parser_lock);
 | |
| ++
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static int parse_mtd_partitions_by_type(struct mtd_info *master,
 | |
| ++					enum mtd_parser_type type,
 | |
| ++					const struct mtd_partition **pparts,
 | |
| ++					struct mtd_part_parser_data *data)
 | |
| ++{
 | |
| ++	struct mtd_part_parser *prev = NULL;
 | |
| ++	int ret = 0;
 | |
| ++
 | |
| ++	while (1) {
 | |
| ++		struct mtd_part_parser *parser;
 | |
| ++
 | |
| ++		parser = get_partition_parser_by_type(type, prev);
 | |
| ++		if (!parser)
 | |
| ++			break;
 | |
| ++
 | |
| ++		ret = (*parser->parse_fn)(master, pparts, data);
 | |
| ++
 | |
| ++		if (ret > 0) {
 | |
| ++			mtd_part_parser_put(parser);
 | |
| ++			printk(KERN_NOTICE
 | |
| ++			       "%d %s partitions found on MTD device %s\n",
 | |
| ++			       ret, parser->name, master->name);
 | |
| ++			break;
 | |
| ++		}
 | |
| ++
 | |
| ++		prev = parser;
 | |
| ++	}
 | |
| ++
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++run_parsers_by_type(struct mtd_info *child, enum mtd_parser_type type)
 | |
| ++{
 | |
| ++	struct mtd_partition *parts;
 | |
| ++	int nr_parts;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	nr_parts = parse_mtd_partitions_by_type(child, type, (const struct mtd_partition **)&parts,
 | |
| ++						NULL);
 | |
| ++	if (nr_parts <= 0)
 | |
| ++		return nr_parts;
 | |
| ++
 | |
| ++	if (WARN_ON(!parts))
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	for (i = 0; i < nr_parts; i++) {
 | |
| ++		/* adjust partition offsets */
 | |
| ++		parts[i].offset += child->part.offset;
 | |
| ++
 | |
| ++		mtd_add_partition(child->parent,
 | |
| ++				  parts[i].name,
 | |
| ++				  parts[i].offset,
 | |
| ++				  parts[i].size);
 | |
| ++	}
 | |
| ++
 | |
| ++	kfree(parts);
 | |
| ++
 | |
| ++	return nr_parts;
 | |
| ++}
 | |
| ++
 | |
| ++#ifdef CONFIG_MTD_SPLIT_FIRMWARE_NAME
 | |
| ++#define SPLIT_FIRMWARE_NAME	CONFIG_MTD_SPLIT_FIRMWARE_NAME
 | |
| ++#else
 | |
| ++#define SPLIT_FIRMWARE_NAME	"unused"
 | |
| ++#endif
 | |
| ++
 | |
| ++static void split_firmware(struct mtd_info *master, struct mtd_info *part)
 | |
| ++{
 | |
| ++	run_parsers_by_type(part, MTD_PARSER_TYPE_FIRMWARE);
 | |
| ++}
 | |
| ++
 | |
| ++static void mtd_partition_split(struct mtd_info *master, struct mtd_info *part)
 | |
| ++{
 | |
| ++	static int rootfs_found = 0;
 | |
| ++
 | |
| ++	if (rootfs_found)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (!strcmp(part->name, "rootfs")) {
 | |
| ++		run_parsers_by_type(part, MTD_PARSER_TYPE_ROOTFS);
 | |
| ++
 | |
| ++		rootfs_found = 1;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (IS_ENABLED(CONFIG_MTD_SPLIT_FIRMWARE) &&
 | |
| ++	    !strcmp(part->name, SPLIT_FIRMWARE_NAME) &&
 | |
| ++	    !of_find_property(mtd_get_of_node(part), "compatible", NULL))
 | |
| ++		split_firmware(master, part);
 | |
| ++}
 | |
| ++
 | |
| + int mtd_add_partition(struct mtd_info *parent, const char *name,
 | |
| + 		      long long offset, long long length)
 | |
| + {
 | |
| +@@ -274,6 +416,7 @@ int mtd_add_partition(struct mtd_info *p
 | |
| + 	if (ret)
 | |
| + 		goto err_remove_part;
 | |
| + 
 | |
| ++	mtd_partition_split(parent, child);
 | |
| + 	mtd_add_partition_attrs(child);
 | |
| + 
 | |
| + 	return 0;
 | |
| +@@ -422,6 +565,7 @@ int add_mtd_partitions(struct mtd_info *
 | |
| + 			goto err_del_partitions;
 | |
| + 		}
 | |
| + 
 | |
| ++		mtd_partition_split(master, child);
 | |
| + 		mtd_add_partition_attrs(child);
 | |
| + 
 | |
| + 		/* Look for subpartitions */
 | |
| +@@ -438,31 +582,6 @@ err_del_partitions:
 | |
| + 	return ret;
 | |
| + }
 | |
| + 
 | |
| +-static DEFINE_SPINLOCK(part_parser_lock);
 | |
| +-static LIST_HEAD(part_parsers);
 | |
| +-
 | |
| +-static struct mtd_part_parser *mtd_part_parser_get(const char *name)
 | |
| +-{
 | |
| +-	struct mtd_part_parser *p, *ret = NULL;
 | |
| +-
 | |
| +-	spin_lock(&part_parser_lock);
 | |
| +-
 | |
| +-	list_for_each_entry(p, &part_parsers, list)
 | |
| +-		if (!strcmp(p->name, name) && try_module_get(p->owner)) {
 | |
| +-			ret = p;
 | |
| +-			break;
 | |
| +-		}
 | |
| +-
 | |
| +-	spin_unlock(&part_parser_lock);
 | |
| +-
 | |
| +-	return ret;
 | |
| +-}
 | |
| +-
 | |
| +-static inline void mtd_part_parser_put(const struct mtd_part_parser *p)
 | |
| +-{
 | |
| +-	module_put(p->owner);
 | |
| +-}
 | |
| +-
 | |
| + /*
 | |
| +  * Many partition parsers just expected the core to kfree() all their data in
 | |
| +  * one chunk. Do that by default.
 | |
| +--- a/include/linux/mtd/partitions.h
 | |
| ++++ b/include/linux/mtd/partitions.h
 | |
| +@@ -75,6 +75,12 @@ struct mtd_part_parser_data {
 | |
| +  * Functions dealing with the various ways of partitioning the space
 | |
| +  */
 | |
| + 
 | |
| ++enum mtd_parser_type {
 | |
| ++	MTD_PARSER_TYPE_DEVICE = 0,
 | |
| ++	MTD_PARSER_TYPE_ROOTFS,
 | |
| ++	MTD_PARSER_TYPE_FIRMWARE,
 | |
| ++};
 | |
| ++
 | |
| + struct mtd_part_parser {
 | |
| + 	struct list_head list;
 | |
| + 	struct module *owner;
 | |
| +@@ -83,6 +89,7 @@ struct mtd_part_parser {
 | |
| + 	int (*parse_fn)(struct mtd_info *, const struct mtd_partition **,
 | |
| + 			struct mtd_part_parser_data *);
 | |
| + 	void (*cleanup)(const struct mtd_partition *pparts, int nr_parts);
 | |
| ++	enum mtd_parser_type type;
 | |
| + };
 | |
| + 
 | |
| + /* Container for passing around a set of parsed partitions */
 | |
| +--- a/drivers/mtd/Makefile
 | |
| ++++ b/drivers/mtd/Makefile
 | |
| +@@ -9,6 +9,8 @@ mtd-y				:= mtdcore.o mtdsuper.o mtdconc
 | |
| + 
 | |
| + obj-y				+= parsers/
 | |
| + 
 | |
| ++obj-$(CONFIG_MTD_SPLIT)		+= mtdsplit/
 | |
| ++
 | |
| + # 'Users' - code which presents functionality to userspace.
 | |
| + obj-$(CONFIG_MTD_BLKDEVS)	+= mtd_blkdevs.o
 | |
| + obj-$(CONFIG_MTD_BLOCK)		+= mtdblock.o
 | |
| +--- a/include/linux/mtd/mtd.h
 | |
| ++++ b/include/linux/mtd/mtd.h
 | |
| +@@ -608,6 +608,24 @@ static inline void mtd_align_erase_req(s
 | |
| + 		req->len += mtd->erasesize - mod;
 | |
| + }
 | |
| + 
 | |
| ++static inline uint64_t mtd_roundup_to_eb(uint64_t sz, struct mtd_info *mtd)
 | |
| ++{
 | |
| ++	if (mtd_mod_by_eb(sz, mtd) == 0)
 | |
| ++		return sz;
 | |
| ++
 | |
| ++	/* Round up to next erase block */
 | |
| ++	return (mtd_div_by_eb(sz, mtd) + 1) * mtd->erasesize;
 | |
| ++}
 | |
| ++
 | |
| ++static inline uint64_t mtd_rounddown_to_eb(uint64_t sz, struct mtd_info *mtd)
 | |
| ++{
 | |
| ++	if (mtd_mod_by_eb(sz, mtd) == 0)
 | |
| ++		return sz;
 | |
| ++
 | |
| ++	/* Round down to the start of the current erase block */
 | |
| ++	return (mtd_div_by_eb(sz, mtd)) * mtd->erasesize;
 | |
| ++}
 | |
| ++
 | |
| + static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
 | |
| + {
 | |
| + 	if (mtd->writesize_shift)
 | |
| +@@ -680,6 +698,13 @@ extern void __put_mtd_device(struct mtd_
 | |
| + extern struct mtd_info *get_mtd_device_nm(const char *name);
 | |
| + extern void put_mtd_device(struct mtd_info *mtd);
 | |
| + 
 | |
| ++static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd)
 | |
| ++{
 | |
| ++	if (!mtd_is_partition(mtd))
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	return mtd->part.offset;
 | |
| ++}
 | |
| + 
 | |
| + struct mtd_notifier {
 | |
| + 	void (*add)(struct mtd_info *mtd);
 | |
| diff --git a/target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch b/target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch
 | |
| new file mode 100644
 | |
| index 0000000000..8358a307cd
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/419-mtd-redboot-add-of_match_table-with-DT-binding.patch
 | |
| @@ -0,0 +1,22 @@
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Subject: [PATCH] mtd: redboot: add of_match_table with DT binding
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This allows parsing RedBoot compatible partitions for properly described
 | |
| +flash device in DT.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/redboot.c
 | |
| ++++ b/drivers/mtd/parsers/redboot.c
 | |
| +@@ -300,6 +300,7 @@ static int parse_redboot_partitions(stru
 | |
| + 
 | |
| + static const struct of_device_id mtd_parser_redboot_of_match_table[] = {
 | |
| + 	{ .compatible = "redboot-fis" },
 | |
| ++	{ .compatible = "ecoscentric,redboot-fis-partitions" },
 | |
| + 	{},
 | |
| + };
 | |
| + MODULE_DEVICE_TABLE(of, mtd_parser_redboot_of_match_table);
 | |
| diff --git a/target/linux/generic/pending-5.10/420-mtd-redboot_space.patch b/target/linux/generic/pending-5.10/420-mtd-redboot_space.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a2cf838989
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/420-mtd-redboot_space.patch
 | |
| @@ -0,0 +1,41 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: add patch for including unpartitioned space in the rootfs partition for redboot devices (if applicable)
 | |
| +
 | |
| +[john@phrozen.org: used by ixp and others]
 | |
| +
 | |
| +lede-commit: 394918851f84e4d00fa16eb900e7700e95091f00
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/mtd/redboot.c | 19 +++++++++++++------
 | |
| + 1 file changed, 13 insertions(+), 6 deletions(-)
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/redboot.c
 | |
| ++++ b/drivers/mtd/parsers/redboot.c
 | |
| +@@ -274,14 +274,21 @@ static int parse_redboot_partitions(stru
 | |
| + #endif
 | |
| + 		names += strlen(names)+1;
 | |
| + 
 | |
| +-#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
 | |
| + 		if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
 | |
| +-			i++;
 | |
| +-			parts[i].offset = parts[i-1].size + parts[i-1].offset;
 | |
| +-			parts[i].size = fl->next->img->flash_base - parts[i].offset;
 | |
| +-			parts[i].name = nullname;
 | |
| +-		}
 | |
| ++			if (!strcmp(parts[i].name, "rootfs")) {
 | |
| ++				parts[i].size = fl->next->img->flash_base;
 | |
| ++				parts[i].size &= ~(master->erasesize - 1);
 | |
| ++				parts[i].size -= parts[i].offset;
 | |
| ++#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
 | |
| ++				nrparts--;
 | |
| ++			} else {
 | |
| ++				i++;
 | |
| ++				parts[i].offset = parts[i-1].size + parts[i-1].offset;
 | |
| ++				parts[i].size = fl->next->img->flash_base - parts[i].offset;
 | |
| ++				parts[i].name = nullname;
 | |
| + #endif
 | |
| ++			}
 | |
| ++		}
 | |
| + 		tmp_fl = fl;
 | |
| + 		fl = fl->next;
 | |
| + 		kfree(tmp_fl);
 | |
| diff --git a/target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch b/target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0889c9a343
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/430-mtd-add-myloader-partition-parser.patch
 | |
| @@ -0,0 +1,229 @@
 | |
| +From: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +Subject: Add myloader partition table parser
 | |
| +
 | |
| +[john@phozen.org: shoud be upstreamable]
 | |
| +
 | |
| +lede-commit: d8bf22859b51faa09d22c056fe221a45d2f7a3b8
 | |
| +Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| +[adjust for kernel 5.4, add myloader.c to patch]
 | |
| +Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/Kconfig
 | |
| ++++ b/drivers/mtd/parsers/Kconfig
 | |
| +@@ -57,6 +57,22 @@ config MTD_CMDLINE_PARTS
 | |
| + 
 | |
| + 	  If unsure, say 'N'.
 | |
| + 
 | |
| ++config MTD_MYLOADER_PARTS
 | |
| ++	tristate "MyLoader partition parsing"
 | |
| ++	depends on ADM5120 || ATH25 || ATH79
 | |
| ++	help
 | |
| ++	  MyLoader is a bootloader which allows the user to define partitions
 | |
| ++	  in flash devices, by putting a table in the second erase block
 | |
| ++	  on the device, similar to a partition table. This table gives the 
 | |
| ++	  offsets and lengths of the user defined partitions.
 | |
| ++
 | |
| ++	  If you need code which can detect and parse these tables, and
 | |
| ++	  register MTD 'partitions' corresponding to each image detected,
 | |
| ++	  enable this option.
 | |
| ++
 | |
| ++	  You will still need the parsing functions to be called by the driver
 | |
| ++	  for your particular device. It won't happen automatically.
 | |
| ++
 | |
| + config MTD_OF_PARTS
 | |
| + 	tristate "OpenFirmware (device tree) partitioning parser"
 | |
| + 	default y
 | |
| +--- a/drivers/mtd/parsers/Makefile
 | |
| ++++ b/drivers/mtd/parsers/Makefile
 | |
| +@@ -3,6 +3,7 @@ obj-$(CONFIG_MTD_AR7_PARTS)		+= ar7part.
 | |
| + obj-$(CONFIG_MTD_BCM47XX_PARTS)		+= bcm47xxpart.o
 | |
| + obj-$(CONFIG_MTD_BCM63XX_PARTS)		+= bcm63xxpart.o
 | |
| + obj-$(CONFIG_MTD_CMDLINE_PARTS)		+= cmdlinepart.o
 | |
| ++obj-$(CONFIG_MTD_MYLOADER_PARTS)		+= myloader.o
 | |
| + obj-$(CONFIG_MTD_OF_PARTS)		+= ofpart.o
 | |
| + ofpart-y				+= ofpart_core.o
 | |
| + ofpart-$(CONFIG_MTD_OF_PARTS_BCM4908)	+= ofpart_bcm4908.o
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/parsers/myloader.c
 | |
| +@@ -0,0 +1,181 @@
 | |
| ++/*
 | |
| ++ *  Parse MyLoader-style flash partition tables and produce a Linux partition
 | |
| ++ *  array to match.
 | |
| ++ *
 | |
| ++ *  Copyright (C) 2007-2009 Gabor Juhos <juhosg@openwrt.org>
 | |
| ++ *
 | |
| ++ *  This file was based on drivers/mtd/redboot.c
 | |
| ++ *  Author: Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>
 | |
| ++ *
 | |
| ++ *  This program is free software; you can redistribute it and/or modify it
 | |
| ++ *  under the terms of the GNU General Public License version 2 as published
 | |
| ++ *  by the Free Software Foundation.
 | |
| ++ */
 | |
| ++
 | |
| ++#include <linux/kernel.h>
 | |
| ++#include <linux/module.h>
 | |
| ++#include <linux/version.h>
 | |
| ++#include <linux/slab.h>
 | |
| ++#include <linux/init.h>
 | |
| ++#include <linux/vmalloc.h>
 | |
| ++#include <linux/mtd/mtd.h>
 | |
| ++#include <linux/mtd/partitions.h>
 | |
| ++#include <linux/byteorder/generic.h>
 | |
| ++#include <linux/myloader.h>
 | |
| ++
 | |
| ++#define BLOCK_LEN_MIN		0x10000
 | |
| ++#define PART_NAME_LEN		32
 | |
| ++
 | |
| ++struct part_data {
 | |
| ++	struct mylo_partition_table	tab;
 | |
| ++	char names[MYLO_MAX_PARTITIONS][PART_NAME_LEN];
 | |
| ++};
 | |
| ++
 | |
| ++static int myloader_parse_partitions(struct mtd_info *master,
 | |
| ++				     const struct mtd_partition **pparts,
 | |
| ++				     struct mtd_part_parser_data *data)
 | |
| ++{
 | |
| ++	struct part_data *buf;
 | |
| ++	struct mylo_partition_table *tab;
 | |
| ++	struct mylo_partition *part;
 | |
| ++	struct mtd_partition *mtd_parts;
 | |
| ++	struct mtd_partition *mtd_part;
 | |
| ++	int num_parts;
 | |
| ++	int ret, i;
 | |
| ++	size_t retlen;
 | |
| ++	char *names;
 | |
| ++	unsigned long offset;
 | |
| ++	unsigned long blocklen;
 | |
| ++
 | |
| ++	buf = vmalloc(sizeof(*buf));
 | |
| ++	if (!buf) {
 | |
| ++		return -ENOMEM;
 | |
| ++		goto out;
 | |
| ++	}
 | |
| ++	tab = &buf->tab;
 | |
| ++
 | |
| ++	blocklen = master->erasesize;
 | |
| ++	if (blocklen < BLOCK_LEN_MIN)
 | |
| ++		blocklen = BLOCK_LEN_MIN;
 | |
| ++
 | |
| ++	offset = blocklen;
 | |
| ++
 | |
| ++	/* Find the partition table */
 | |
| ++	for (i = 0; i < 4; i++, offset += blocklen) {
 | |
| ++		printk(KERN_DEBUG "%s: searching for MyLoader partition table"
 | |
| ++				" at offset 0x%lx\n", master->name, offset);
 | |
| ++
 | |
| ++		ret = mtd_read(master, offset, sizeof(*buf), &retlen,
 | |
| ++			       (void *)buf);
 | |
| ++		if (ret)
 | |
| ++			goto out_free_buf;
 | |
| ++
 | |
| ++		if (retlen != sizeof(*buf)) {
 | |
| ++			ret = -EIO;
 | |
| ++			goto out_free_buf;
 | |
| ++		}
 | |
| ++
 | |
| ++		/* Check for Partition Table magic number */
 | |
| ++		if (tab->magic == le32_to_cpu(MYLO_MAGIC_PARTITIONS))
 | |
| ++			break;
 | |
| ++
 | |
| ++	}
 | |
| ++
 | |
| ++	if (tab->magic != le32_to_cpu(MYLO_MAGIC_PARTITIONS)) {
 | |
| ++		printk(KERN_DEBUG "%s: no MyLoader partition table found\n",
 | |
| ++			master->name);
 | |
| ++		ret = 0;
 | |
| ++		goto out_free_buf;
 | |
| ++	}
 | |
| ++
 | |
| ++	/* The MyLoader and the Partition Table is always present */
 | |
| ++	num_parts = 2;
 | |
| ++
 | |
| ++	/* Detect number of used partitions */
 | |
| ++	for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
 | |
| ++		part = &tab->partitions[i];
 | |
| ++
 | |
| ++		if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		num_parts++;
 | |
| ++	}
 | |
| ++
 | |
| ++	mtd_parts = kzalloc((num_parts * sizeof(*mtd_part) +
 | |
| ++				num_parts * PART_NAME_LEN), GFP_KERNEL);
 | |
| ++
 | |
| ++	if (!mtd_parts) {
 | |
| ++		ret = -ENOMEM;
 | |
| ++		goto out_free_buf;
 | |
| ++	}
 | |
| ++
 | |
| ++	mtd_part = mtd_parts;
 | |
| ++	names = (char *)&mtd_parts[num_parts];
 | |
| ++
 | |
| ++	strncpy(names, "myloader", PART_NAME_LEN);
 | |
| ++	mtd_part->name = names;
 | |
| ++	mtd_part->offset = 0;
 | |
| ++	mtd_part->size = offset;
 | |
| ++	mtd_part->mask_flags = MTD_WRITEABLE;
 | |
| ++	mtd_part++;
 | |
| ++	names += PART_NAME_LEN;
 | |
| ++
 | |
| ++	strncpy(names, "partition_table", PART_NAME_LEN);
 | |
| ++	mtd_part->name = names;
 | |
| ++	mtd_part->offset = offset;
 | |
| ++	mtd_part->size = blocklen;
 | |
| ++	mtd_part->mask_flags = MTD_WRITEABLE;
 | |
| ++	mtd_part++;
 | |
| ++	names += PART_NAME_LEN;
 | |
| ++
 | |
| ++	for (i = 0; i < MYLO_MAX_PARTITIONS; i++) {
 | |
| ++		part = &tab->partitions[i];
 | |
| ++
 | |
| ++		if (le16_to_cpu(part->type) == PARTITION_TYPE_FREE)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		if ((buf->names[i][0]) && (buf->names[i][0] != '\xff'))
 | |
| ++			strncpy(names, buf->names[i], PART_NAME_LEN);
 | |
| ++		else
 | |
| ++			snprintf(names, PART_NAME_LEN, "partition%d", i);
 | |
| ++
 | |
| ++		mtd_part->offset = le32_to_cpu(part->addr);
 | |
| ++		mtd_part->size = le32_to_cpu(part->size);
 | |
| ++		mtd_part->name = names;
 | |
| ++		mtd_part++;
 | |
| ++		names += PART_NAME_LEN;
 | |
| ++	}
 | |
| ++
 | |
| ++	*pparts = mtd_parts;
 | |
| ++	ret = num_parts;
 | |
| ++
 | |
| ++ out_free_buf:
 | |
| ++	vfree(buf);
 | |
| ++ out:
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++static struct mtd_part_parser myloader_mtd_parser = {
 | |
| ++	.owner		= THIS_MODULE,
 | |
| ++	.parse_fn	= myloader_parse_partitions,
 | |
| ++	.name		= "MyLoader",
 | |
| ++};
 | |
| ++
 | |
| ++static int __init myloader_mtd_parser_init(void)
 | |
| ++{
 | |
| ++	register_mtd_parser(&myloader_mtd_parser);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void __exit myloader_mtd_parser_exit(void)
 | |
| ++{
 | |
| ++	deregister_mtd_parser(&myloader_mtd_parser);
 | |
| ++}
 | |
| ++
 | |
| ++module_init(myloader_mtd_parser_init);
 | |
| ++module_exit(myloader_mtd_parser_exit);
 | |
| ++
 | |
| ++MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
 | |
| ++MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
 | |
| ++MODULE_LICENSE("GPL v2");
 | |
| diff --git a/target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch b/target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2ea59cd872
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/431-mtd-bcm47xxpart-check-for-bad-blocks-when-calculatin.patch
 | |
| @@ -0,0 +1,68 @@
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | |
| +Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating offsets
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/parser_trx.c
 | |
| ++++ b/drivers/mtd/parsers/parser_trx.c
 | |
| +@@ -25,6 +25,33 @@ struct trx_header {
 | |
| + 	uint32_t offset[3];
 | |
| + } __packed;
 | |
| + 
 | |
| ++/*
 | |
| ++ * Calculate real end offset (address) for a given amount of data. It checks
 | |
| ++ * all blocks skipping bad ones.
 | |
| ++ */
 | |
| ++static size_t parser_trx_real_offset(struct mtd_info *mtd, size_t bytes)
 | |
| ++{
 | |
| ++	size_t real_offset = 0;
 | |
| ++
 | |
| ++	if (mtd_block_isbad(mtd, real_offset))
 | |
| ++		pr_warn("Base offset shouldn't be at bad block");
 | |
| ++
 | |
| ++	while (bytes >= mtd->erasesize) {
 | |
| ++		bytes -= mtd->erasesize;
 | |
| ++		real_offset += mtd->erasesize;
 | |
| ++		while (mtd_block_isbad(mtd, real_offset)) {
 | |
| ++			real_offset += mtd->erasesize;
 | |
| ++
 | |
| ++			if (real_offset >= mtd->size)
 | |
| ++				return real_offset - mtd->erasesize;
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	real_offset += bytes;
 | |
| ++
 | |
| ++	return real_offset;
 | |
| ++}
 | |
| ++
 | |
| + static const char *parser_trx_data_part_name(struct mtd_info *master,
 | |
| + 					     size_t offset)
 | |
| + {
 | |
| +@@ -79,21 +106,21 @@ static int parser_trx_parse(struct mtd_i
 | |
| + 	if (trx.offset[2]) {
 | |
| + 		part = &parts[curr_part++];
 | |
| + 		part->name = "loader";
 | |
| +-		part->offset = trx.offset[i];
 | |
| ++		part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
 | |
| + 		i++;
 | |
| + 	}
 | |
| + 
 | |
| + 	if (trx.offset[i]) {
 | |
| + 		part = &parts[curr_part++];
 | |
| + 		part->name = "linux";
 | |
| +-		part->offset = trx.offset[i];
 | |
| ++		part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
 | |
| + 		i++;
 | |
| + 	}
 | |
| + 
 | |
| + 	if (trx.offset[i]) {
 | |
| + 		part = &parts[curr_part++];
 | |
| +-		part->name = parser_trx_data_part_name(mtd, trx.offset[i]);
 | |
| +-		part->offset = trx.offset[i];
 | |
| ++		part->offset = parser_trx_real_offset(mtd, trx.offset[i]);
 | |
| ++		part->name = parser_trx_data_part_name(mtd, part->offset);
 | |
| + 		i++;
 | |
| + 	}
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch b/target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
 | |
| new file mode 100644
 | |
| index 0000000000..852654d924
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/432-mtd-bcm47xxpart-detect-T_Meter-partition.patch
 | |
| @@ -0,0 +1,37 @@
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
 | |
| +Subject: mtd: bcm47xxpart: detect T_Meter partition
 | |
| +
 | |
| +It can be found on many Netgear devices. It consists of many 0x30 blocks
 | |
| +starting with 4D 54.
 | |
| +
 | |
| +Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 | |
| +---
 | |
| + drivers/mtd/bcm47xxpart.c | 10 ++++++++++
 | |
| + 1 file changed, 10 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/bcm47xxpart.c
 | |
| ++++ b/drivers/mtd/parsers/bcm47xxpart.c
 | |
| +@@ -35,6 +35,7 @@
 | |
| + #define NVRAM_HEADER			0x48534C46	/* FLSH */
 | |
| + #define POT_MAGIC1			0x54544f50	/* POTT */
 | |
| + #define POT_MAGIC2			0x504f		/* OP */
 | |
| ++#define T_METER_MAGIC			0x4D540000	/* MT */
 | |
| + #define ML_MAGIC1			0x39685a42
 | |
| + #define ML_MAGIC2			0x26594131
 | |
| + #define TRX_MAGIC			0x30524448
 | |
| +@@ -178,6 +179,15 @@ static int bcm47xxpart_parse(struct mtd_
 | |
| + 					     MTD_WRITEABLE);
 | |
| + 			continue;
 | |
| + 		}
 | |
| ++
 | |
| ++		/* T_Meter */
 | |
| ++		if ((le32_to_cpu(buf[0x000 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
 | |
| ++		    (le32_to_cpu(buf[0x030 / 4]) & 0xFFFF0000) == T_METER_MAGIC &&
 | |
| ++		    (le32_to_cpu(buf[0x060 / 4]) & 0xFFFF0000) == T_METER_MAGIC) {
 | |
| ++			bcm47xxpart_add_part(&parts[curr_part++], "T_Meter", offset,
 | |
| ++					     MTD_WRITEABLE);
 | |
| ++			continue;
 | |
| ++		}
 | |
| + 
 | |
| + 		/* TRX */
 | |
| + 		if (buf[0x000 / 4] == TRX_MAGIC) {
 | |
| diff --git a/target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch b/target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch
 | |
| new file mode 100644
 | |
| index 0000000000..ab1e09a5f1
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/435-mtd-add-routerbootpart-parser-config.patch
 | |
| @@ -0,0 +1,38 @@
 | |
| +From 4437e01fb6bca63fccdba5d6c44888b0935885c2 Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Thibaut=20VAR=C3=88NE?= <hacks@slashdirt.org>
 | |
| +Date: Tue, 24 Mar 2020 11:45:07 +0100
 | |
| +Subject: [PATCH] generic: routerboot partition build bits (5.4)
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This patch adds routerbootpart kernel build bits
 | |
| +
 | |
| +Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
 | |
| +---
 | |
| + drivers/mtd/parsers/Kconfig  | 9 +++++++++
 | |
| + drivers/mtd/parsers/Makefile | 1 +
 | |
| + 2 files changed, 10 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/parsers/Kconfig
 | |
| ++++ b/drivers/mtd/parsers/Kconfig
 | |
| +@@ -195,3 +195,12 @@ config MTD_REDBOOT_PARTS_READONLY
 | |
| + 	  'FIS directory' images, enable this option.
 | |
| + 
 | |
| + endif # MTD_REDBOOT_PARTS
 | |
| ++
 | |
| ++config MTD_ROUTERBOOT_PARTS
 | |
| ++	tristate "RouterBoot flash partition parser"
 | |
| ++	depends on MTD && OF
 | |
| ++	help
 | |
| ++	 MikroTik RouterBoot is implemented as a multi segment system on the
 | |
| ++	 flash, some of which are fixed and some of which are located at
 | |
| ++	 variable offsets. This parser handles both cases via properly
 | |
| ++	 formatted DTS.
 | |
| +--- a/drivers/mtd/parsers/Makefile
 | |
| ++++ b/drivers/mtd/parsers/Makefile
 | |
| +@@ -13,3 +13,4 @@ obj-$(CONFIG_MTD_AFS_PARTS)		+= afs.o
 | |
| + obj-$(CONFIG_MTD_PARSER_TRX)		+= parser_trx.o
 | |
| + obj-$(CONFIG_MTD_SHARPSL_PARTS)		+= sharpslpart.o
 | |
| + obj-$(CONFIG_MTD_REDBOOT_PARTS)		+= redboot.o
 | |
| ++obj-$(CONFIG_MTD_ROUTERBOOT_PARTS)		+= routerbootpart.o
 | |
| diff --git a/target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch b/target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
 | |
| new file mode 100644
 | |
| index 0000000000..659a6386ae
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/460-mtd-cfi_cmdset_0002-no-erase_suspend.patch
 | |
| @@ -0,0 +1,25 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: kernel: disable cfi cmdset 0002 erase suspend
 | |
| +
 | |
| +on some platforms, erase suspend leads to data corruption and lockups when write
 | |
| +ops collide with erase ops. this has been observed on the buffalo wzr-hp-g300nh.
 | |
| +rather than play whack-a-mole with a hard to reproduce issue on a variety of devices,
 | |
| +simply disable erase suspend, as it will usually not produce any useful gain on
 | |
| +the small filesystems used on embedded hardware.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/mtd/chips/cfi_cmdset_0002.c | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/drivers/mtd/chips/cfi_cmdset_0002.c
 | |
| ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 | |
| +@@ -909,7 +909,7 @@ static int get_chip(struct map_info *map
 | |
| + 		return 0;
 | |
| + 
 | |
| + 	case FL_ERASING:
 | |
| +-		if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
 | |
| ++		if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
 | |
| + 		    !(mode == FL_READY || mode == FL_POINT ||
 | |
| + 		    (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
 | |
| + 			goto sleep;
 | |
| diff --git a/target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch b/target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch
 | |
| new file mode 100644
 | |
| index 0000000000..79276b1b87
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/461-mtd-cfi_cmdset_0002-add-buffer-write-cmd-timeout.patch
 | |
| @@ -0,0 +1,17 @@
 | |
| +From: George Kashperko <george@znau.edu.ua>
 | |
| +Subject: Issue map read after Write Buffer Load command to ensure chip is ready to receive data.
 | |
| +
 | |
| +Signed-off-by: George Kashperko <george@znau.edu.ua>
 | |
| +---
 | |
| + drivers/mtd/chips/cfi_cmdset_0002.c |    1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +--- a/drivers/mtd/chips/cfi_cmdset_0002.c
 | |
| ++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
 | |
| +@@ -2053,6 +2053,7 @@ static int __xipram do_write_buffer(stru
 | |
| + 
 | |
| + 	/* Write Buffer Load */
 | |
| + 	map_write(map, CMD(0x25), cmd_adr);
 | |
| ++	(void) map_read(map, cmd_adr);
 | |
| + 
 | |
| + 	chip->state = FL_WRITING_TO_BUFFER;
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch b/target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e9a9cad869
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/465-m25p80-mx-disable-software-protection.patch
 | |
| @@ -0,0 +1,18 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: Disable software protection bits for Macronix flashes.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/mtd/spi-nor/spi-nor.c | 1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/drivers/mtd/spi-nor/macronix.c
 | |
| ++++ b/drivers/mtd/spi-nor/macronix.c
 | |
| +@@ -96,6 +96,7 @@ static void macronix_default_init(struct
 | |
| + {
 | |
| + 	nor->params->quad_enable = spi_nor_sr1_bit6_quad_enable;
 | |
| + 	nor->params->set_4byte_addr_mode = spi_nor_set_4byte_addr_mode;
 | |
| ++	nor->flags |= SNOR_F_HAS_LOCK;
 | |
| + }
 | |
| + 
 | |
| + static const struct spi_nor_fixups macronix_fixups = {
 | |
| diff --git a/target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch b/target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch
 | |
| new file mode 100644
 | |
| index 0000000000..d000094e1d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/470-mtd-spi-nor-support-limiting-4K-sectors-support-base.patch
 | |
| @@ -0,0 +1,71 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sat, 4 Nov 2017 07:40:23 +0100
 | |
| +Subject: [PATCH] mtd: spi-nor: support limiting 4K sectors support based on
 | |
| + flash size
 | |
| +
 | |
| +Some devices need 4K sectors to be able to deal with small flash chips.
 | |
| +For instance, w25x05 is 64 KiB in size, and without 4K sectors, the
 | |
| +entire chip is just one erase block.
 | |
| +On bigger flash chip sizes, using 4K sectors can significantly slow down
 | |
| +many operations, including using a writable filesystem. There are several
 | |
| +platforms where it makes sense to use a single kernel on both kinds of
 | |
| +devices.
 | |
| +
 | |
| +To support this properly, allow configuring an upper flash chip size
 | |
| +limit for 4K sectors support.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/mtd/spi-nor/Kconfig
 | |
| ++++ b/drivers/mtd/spi-nor/Kconfig
 | |
| +@@ -24,6 +24,17 @@ config MTD_SPI_NOR_USE_4K_SECTORS
 | |
| + 	  Please note that some tools/drivers/filesystems may not work with
 | |
| + 	  4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum).
 | |
| + 
 | |
| ++config MTD_SPI_NOR_USE_4K_SECTORS_LIMIT
 | |
| ++	int "Maximum flash chip size to use 4K sectors on (in KiB)"
 | |
| ++	depends on MTD_SPI_NOR_USE_4K_SECTORS
 | |
| ++	default "4096"
 | |
| ++	help
 | |
| ++	  There are many flash chips that support 4K sectors, but are so large
 | |
| ++	  that using them significantly slows down writing large amounts of
 | |
| ++	  data or using a writable filesystem.
 | |
| ++	  Any flash chip larger than the size specified in this option will
 | |
| ++	  not use 4K sectors.
 | |
| ++
 | |
| + source "drivers/mtd/spi-nor/controllers/Kconfig"
 | |
| + 
 | |
| + endif # MTD_SPI_NOR
 | |
| +--- a/drivers/mtd/spi-nor/core.c
 | |
| ++++ b/drivers/mtd/spi-nor/core.c
 | |
| +@@ -2786,6 +2786,21 @@ static void spi_nor_info_init_params(str
 | |
| + 	 */
 | |
| + 	erase_mask = 0;
 | |
| + 	i = 0;
 | |
| ++#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
 | |
| ++	if ((info->flags & SECT_4K_PMC) && (params->size <=
 | |
| ++		   CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) {
 | |
| ++		erase_mask |= BIT(i);
 | |
| ++		spi_nor_set_erase_type(&map->erase_type[i], 4096u,
 | |
| ++				       SPINOR_OP_BE_4K_PMC);
 | |
| ++		i++;
 | |
| ++	} else if ((info->flags & SECT_4K) && (params->size <=
 | |
| ++	    CONFIG_MTD_SPI_NOR_USE_4K_SECTORS_LIMIT * 1024)) {
 | |
| ++		erase_mask |= BIT(i);
 | |
| ++		spi_nor_set_erase_type(&map->erase_type[i], 4096u,
 | |
| ++				       SPINOR_OP_BE_4K);
 | |
| ++		i++;
 | |
| ++	}
 | |
| ++#else
 | |
| + 	if (info->flags & SECT_4K_PMC) {
 | |
| + 		erase_mask |= BIT(i);
 | |
| + 		spi_nor_set_erase_type(&map->erase_type[i], 4096u,
 | |
| +@@ -2797,6 +2812,7 @@ static void spi_nor_info_init_params(str
 | |
| + 				       SPINOR_OP_BE_4K);
 | |
| + 		i++;
 | |
| + 	}
 | |
| ++#endif
 | |
| + 	erase_mask |= BIT(i);
 | |
| + 	spi_nor_set_erase_type(&map->erase_type[i], info->sector_size,
 | |
| + 			       SPINOR_OP_SE);
 | |
| diff --git a/target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch b/target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch
 | |
| new file mode 100644
 | |
| index 0000000000..325fca62f3
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/476-mtd-spi-nor-add-eon-en25q128.patch
 | |
| @@ -0,0 +1,18 @@
 | |
| +From: Piotr Dymacz <pepe2k@gmail.com>
 | |
| +Subject: kernel/mtd: add support for EON EN25Q128
 | |
| +
 | |
| +Signed-off-by: Piotr Dymacz <pepe2k@gmail.com>
 | |
| +---
 | |
| + drivers/mtd/spi-nor/spi-nor.c | 1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/drivers/mtd/spi-nor/eon.c
 | |
| ++++ b/drivers/mtd/spi-nor/eon.c
 | |
| +@@ -15,6 +15,7 @@ static const struct flash_info eon_parts
 | |
| + 	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
 | |
| + 	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
 | |
| + 	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
 | |
| ++	{ "en25q128",   INFO(0x1c3018, 0, 64 * 1024,  256, SECT_4K) },
 | |
| + 	{ "en25q80a",   INFO(0x1c3014, 0, 64 * 1024,   16,
 | |
| + 			     SECT_4K | SPI_NOR_DUAL_READ) },
 | |
| + 	{ "en25qh16",   INFO(0x1c7015, 0, 64 * 1024,   32,
 | |
| diff --git a/target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch b/target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch
 | |
| new file mode 100644
 | |
| index 0000000000..9ff6ffae58
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/479-mtd-spi-nor-add-xtx-xt25f128b.patch
 | |
| @@ -0,0 +1,79 @@
 | |
| +From patchwork Thu Feb  6 17:19:41 2020
 | |
| +Content-Type: text/plain; charset="utf-8"
 | |
| +MIME-Version: 1.0
 | |
| +Content-Transfer-Encoding: 7bit
 | |
| +X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
 | |
| +X-Patchwork-Id: 1234465
 | |
| +Date: Thu, 6 Feb 2020 19:19:41 +0200
 | |
| +From: Daniel Golle <daniel@makrotopia.org>
 | |
| +To: linux-mtd@lists.infradead.org
 | |
| +Subject: [PATCH v2] mtd: spi-nor: Add support for xt25f128b chip
 | |
| +Message-ID: <20200206171941.GA2398@makrotopia.org>
 | |
| +MIME-Version: 1.0
 | |
| +Content-Disposition: inline
 | |
| +List-Subscribe: <http://lists.infradead.org/mailman/listinfo/linux-mtd>,
 | |
| + <mailto:linux-mtd-request@lists.infradead.org?subject=subscribe>
 | |
| +Cc: Eitan Cohen <eitan@neot-semadar.com>, Piotr Dymacz <pepe2k@gmail.com>,
 | |
| + Tudor Ambarus <tudor.ambarus@microchip.com>
 | |
| +Sender: "linux-mtd" <linux-mtd-bounces@lists.infradead.org>
 | |
| +Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org
 | |
| +
 | |
| +Add XT25F128B made by XTX Technology (Shenzhen) Limited.
 | |
| +This chip supports dual and quad read and uniform 4K-byte erase.
 | |
| +Verified on Teltonika RUT955 which comes with XT25F128B in recent
 | |
| +versions of the device.
 | |
| +
 | |
| +Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/mtd/spi-nor/spi-nor.c | 4 ++++
 | |
| + 1 file changed, 4 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/spi-nor/Makefile
 | |
| ++++ b/drivers/mtd/spi-nor/Makefile
 | |
| +@@ -17,6 +17,7 @@ spi-nor-objs			+= sst.o
 | |
| + spi-nor-objs			+= winbond.o
 | |
| + spi-nor-objs			+= xilinx.o
 | |
| + spi-nor-objs			+= xmc.o
 | |
| ++spi-nor-objs			+= xtx.o
 | |
| + obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor.o
 | |
| + 
 | |
| + obj-$(CONFIG_MTD_SPI_NOR)	+= controllers/
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/spi-nor/xtx.c
 | |
| +@@ -0,0 +1,15 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0
 | |
| ++#include <linux/mtd/spi-nor.h>
 | |
| ++
 | |
| ++#include "core.h"
 | |
| ++
 | |
| ++static const struct flash_info xtx_parts[] = {
 | |
| ++	/* XTX Technology (Shenzhen) Limited */
 | |
| ++	{ "xt25f128b", INFO(0x0B4018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 | |
| ++};
 | |
| ++
 | |
| ++const struct spi_nor_manufacturer spi_nor_xtx = {
 | |
| ++	.name = "xtx",
 | |
| ++	.parts = xtx_parts,
 | |
| ++	.nparts = ARRAY_SIZE(xtx_parts),
 | |
| ++};
 | |
| +--- a/drivers/mtd/spi-nor/core.c
 | |
| ++++ b/drivers/mtd/spi-nor/core.c
 | |
| +@@ -2026,6 +2026,7 @@ static const struct spi_nor_manufacturer
 | |
| + 	&spi_nor_winbond,
 | |
| + 	&spi_nor_xilinx,
 | |
| + 	&spi_nor_xmc,
 | |
| ++	&spi_nor_xtx,
 | |
| + };
 | |
| + 
 | |
| + static const struct flash_info *
 | |
| +--- a/drivers/mtd/spi-nor/core.h
 | |
| ++++ b/drivers/mtd/spi-nor/core.h
 | |
| +@@ -398,6 +398,7 @@ extern const struct spi_nor_manufacturer
 | |
| + extern const struct spi_nor_manufacturer spi_nor_winbond;
 | |
| + extern const struct spi_nor_manufacturer spi_nor_xilinx;
 | |
| + extern const struct spi_nor_manufacturer spi_nor_xmc;
 | |
| ++extern const struct spi_nor_manufacturer spi_nor_xtx;
 | |
| + 
 | |
| + int spi_nor_write_enable(struct spi_nor *nor);
 | |
| + int spi_nor_write_disable(struct spi_nor *nor);
 | |
| diff --git a/target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch b/target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e01b991942
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/480-mtd-set-rootfs-to-be-root-dev.patch
 | |
| @@ -0,0 +1,38 @@
 | |
| +From: Gabor Juhos <juhosg@openwrt.org>
 | |
| +Subject: kernel/3.1[02]: move MTD root device setup code to mtdcore
 | |
| +
 | |
| +The current code only allows to automatically set
 | |
| +root device on MTD partitions. Move the code to MTD
 | |
| +core to allow to use it with all MTD devices.
 | |
| +
 | |
| +Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 | |
| +---
 | |
| + drivers/mtd/mtdcore.c | 10 ++++++++++
 | |
| + 1 file changed, 10 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/mtdcore.c
 | |
| ++++ b/drivers/mtd/mtdcore.c
 | |
| +@@ -27,6 +27,7 @@
 | |
| + #include <linux/reboot.h>
 | |
| + #include <linux/leds.h>
 | |
| + #include <linux/debugfs.h>
 | |
| ++#include <linux/root_dev.h>
 | |
| + #include <linux/nvmem-provider.h>
 | |
| + 
 | |
| + #include <linux/mtd/mtd.h>
 | |
| +@@ -693,6 +694,15 @@ int add_mtd_device(struct mtd_info *mtd)
 | |
| + 	   of this try_ nonsense, and no bitching about it
 | |
| + 	   either. :) */
 | |
| + 	__module_get(THIS_MODULE);
 | |
| ++
 | |
| ++	if (!strcmp(mtd->name, "rootfs") &&
 | |
| ++	    IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
 | |
| ++	    ROOT_DEV == 0) {
 | |
| ++		pr_notice("mtd: device %d (%s) set to be root filesystem\n",
 | |
| ++			  mtd->index, mtd->name);
 | |
| ++		ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
 | |
| ++	}
 | |
| ++
 | |
| + 	return 0;
 | |
| + 
 | |
| + fail_nvmem_add:
 | |
| diff --git a/target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch b/target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..5cb85172fb
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/481-mtd-spi-nor-rework-broken-flash-reset-support.patch
 | |
| @@ -0,0 +1,180 @@
 | |
| +From ea92cbb50a78404e29de2cc3999a240615ffb1c8 Mon Sep 17 00:00:00 2001
 | |
| +From: Chuanhong Guo <gch981213@gmail.com>
 | |
| +Date: Mon, 6 Apr 2020 17:58:48 +0800
 | |
| +Subject: [PATCH] mtd: spi-nor: rework broken-flash-reset support
 | |
| +
 | |
| +Instead of resetting flash to 3B address on remove hook, this
 | |
| +implementation only enters 4B mode when needed, which prevents
 | |
| +more unexpected reboot stuck. This implementation makes it only
 | |
| +break when a kernel panic happens during flash operation on 16M+
 | |
| +areas.
 | |
| +*OpenWrt only*: silent broken-flash-reset warning. We are not dealing
 | |
| +with vendors and it's unpleasant for users to se that unnecessary
 | |
| +and long WARN_ON print.
 | |
| +
 | |
| +Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
 | |
| +---
 | |
| + drivers/mtd/spi-nor/spi-nor.c | 52 +++++++++++++++++++++++++++++++++--
 | |
| + 1 file changed, 49 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/drivers/mtd/spi-nor/core.c
 | |
| ++++ b/drivers/mtd/spi-nor/core.c
 | |
| +@@ -1447,6 +1447,23 @@ destroy_erase_cmd_list:
 | |
| + 	return ret;
 | |
| + }
 | |
| + 
 | |
| ++int spi_nor_check_set_addr_width(struct spi_nor *nor, loff_t addr)
 | |
| ++{
 | |
| ++	u8 addr_width;
 | |
| ++
 | |
| ++	if ((nor->flags & (SNOR_F_4B_OPCODES | SNOR_F_BROKEN_RESET)) !=
 | |
| ++	    SNOR_F_BROKEN_RESET)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	addr_width = addr & 0xff000000 ? 4 : 3;
 | |
| ++	if (nor->addr_width == addr_width)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	nor->addr_width = addr_width;
 | |
| ++
 | |
| ++	return nor->params->set_4byte_addr_mode(nor, addr_width == 4);
 | |
| ++}
 | |
| ++
 | |
| + /*
 | |
| +  * Erase an address range on the nor chip.  The address range may extend
 | |
| +  * one or more erase sectors.  Return an error is there is a problem erasing.
 | |
| +@@ -1474,6 +1491,10 @@ static int spi_nor_erase(struct mtd_info
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	ret = spi_nor_check_set_addr_width(nor, instr->addr + instr->len);
 | |
| ++	if (ret < 0)
 | |
| ++		return ret;
 | |
| ++
 | |
| + 	/* whole-chip erase? */
 | |
| + 	if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
 | |
| + 		unsigned long timeout;
 | |
| +@@ -1533,6 +1554,7 @@ static int spi_nor_erase(struct mtd_info
 | |
| + 	ret = spi_nor_write_disable(nor);
 | |
| + 
 | |
| + erase_err:
 | |
| ++	spi_nor_check_set_addr_width(nor, 0);
 | |
| + 	spi_nor_unlock_and_unprep(nor);
 | |
| + 
 | |
| + 	return ret;
 | |
| +@@ -1872,7 +1894,9 @@ static int spi_nor_lock(struct mtd_info
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	spi_nor_check_set_addr_width(nor, ofs + len);
 | |
| + 	ret = nor->params->locking_ops->lock(nor, ofs, len);
 | |
| ++	spi_nor_check_set_addr_width(nor, 0);
 | |
| + 
 | |
| + 	spi_nor_unlock_and_unprep(nor);
 | |
| + 	return ret;
 | |
| +@@ -1887,7 +1911,9 @@ static int spi_nor_unlock(struct mtd_inf
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	spi_nor_check_set_addr_width(nor, ofs + len);
 | |
| + 	ret = nor->params->locking_ops->unlock(nor, ofs, len);
 | |
| ++	spi_nor_check_set_addr_width(nor, 0);
 | |
| + 
 | |
| + 	spi_nor_unlock_and_unprep(nor);
 | |
| + 	return ret;
 | |
| +@@ -1902,7 +1928,9 @@ static int spi_nor_is_locked(struct mtd_
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	spi_nor_check_set_addr_width(nor, ofs + len);
 | |
| + 	ret = nor->params->locking_ops->is_locked(nor, ofs, len);
 | |
| ++	spi_nor_check_set_addr_width(nor, 0);
 | |
| + 
 | |
| + 	spi_nor_unlock_and_unprep(nor);
 | |
| + 	return ret;
 | |
| +@@ -2095,6 +2123,10 @@ static int spi_nor_read(struct mtd_info
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	ret = spi_nor_check_set_addr_width(nor, from + len);
 | |
| ++	if (ret < 0)
 | |
| ++		return ret;
 | |
| ++
 | |
| + 	while (len) {
 | |
| + 		loff_t addr = from;
 | |
| + 
 | |
| +@@ -2118,6 +2150,7 @@ static int spi_nor_read(struct mtd_info
 | |
| + 	ret = 0;
 | |
| + 
 | |
| + read_err:
 | |
| ++	spi_nor_check_set_addr_width(nor, 0);
 | |
| + 	spi_nor_unlock_and_unprep(nor);
 | |
| + 	return ret;
 | |
| + }
 | |
| +@@ -2140,6 +2173,10 @@ static int spi_nor_write(struct mtd_info
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	ret = spi_nor_check_set_addr_width(nor, to + len);
 | |
| ++	if (ret < 0)
 | |
| ++		return ret;
 | |
| ++
 | |
| + 	for (i = 0; i < len; ) {
 | |
| + 		ssize_t written;
 | |
| + 		loff_t addr = to + i;
 | |
| +@@ -2182,6 +2219,7 @@ static int spi_nor_write(struct mtd_info
 | |
| + 	}
 | |
| + 
 | |
| + write_err:
 | |
| ++	spi_nor_check_set_addr_width(nor, 0);
 | |
| + 	spi_nor_unlock_and_unprep(nor);
 | |
| + 	return ret;
 | |
| + }
 | |
| +@@ -2977,9 +3015,13 @@ static int spi_nor_init(struct spi_nor *
 | |
| + 		 * reboots (e.g., crashes). Warn the user (or hopefully, system
 | |
| + 		 * designer) that this is bad.
 | |
| + 		 */
 | |
| +-		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
 | |
| +-			  "enabling reset hack; may not recover from unexpected reboots\n");
 | |
| +-		nor->params->set_4byte_addr_mode(nor, true);
 | |
| ++		if (nor->flags & SNOR_F_BROKEN_RESET) {
 | |
| ++			dev_warn(nor->dev,
 | |
| ++				"enabling reset hack; may not recover from unexpected reboots\n");
 | |
| ++			nor->addr_width = 3;
 | |
| ++		} else {
 | |
| ++			nor->params->set_4byte_addr_mode(nor, true);
 | |
| ++		}
 | |
| + 	}
 | |
| + 
 | |
| + 	return 0;
 | |
| +--- a/drivers/mtd/spi-nor/core.h
 | |
| ++++ b/drivers/mtd/spi-nor/core.h
 | |
| +@@ -400,6 +400,7 @@ extern const struct spi_nor_manufacturer
 | |
| + extern const struct spi_nor_manufacturer spi_nor_xmc;
 | |
| + extern const struct spi_nor_manufacturer spi_nor_xtx;
 | |
| + 
 | |
| ++int spi_nor_check_set_addr_width(struct spi_nor *nor, loff_t addr);
 | |
| + int spi_nor_write_enable(struct spi_nor *nor);
 | |
| + int spi_nor_write_disable(struct spi_nor *nor);
 | |
| + int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable);
 | |
| +--- a/drivers/mtd/spi-nor/sst.c
 | |
| ++++ b/drivers/mtd/spi-nor/sst.c
 | |
| +@@ -55,6 +55,10 @@ static int sst_write(struct mtd_info *mt
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	ret = spi_nor_check_set_addr_width(nor, to + len);
 | |
| ++	if (ret < 0)
 | |
| ++		return ret;
 | |
| ++
 | |
| + 	ret = spi_nor_write_enable(nor);
 | |
| + 	if (ret)
 | |
| + 		goto out;
 | |
| +@@ -124,6 +128,7 @@ static int sst_write(struct mtd_info *mt
 | |
| + 	}
 | |
| + out:
 | |
| + 	*retlen += actual;
 | |
| ++	spi_nor_check_set_addr_width(nor, 0);
 | |
| + 	spi_nor_unlock_and_unprep(nor);
 | |
| + 	return ret;
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch b/target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch
 | |
| new file mode 100644
 | |
| index 0000000000..c32cde559d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/482-mtd-spi-nor-add-support-for-Gigadevice-GD25D05.patch
 | |
| @@ -0,0 +1,22 @@
 | |
| +From d68b4aa22e8c625685bfad642dd7337948dc0ad1 Mon Sep 17 00:00:00 2001
 | |
| +From: Koen Vandeputte <koen.vandeputte@ncentric.com>
 | |
| +Date: Mon, 6 Jan 2020 13:07:56 +0100
 | |
| +Subject: [PATCH] mtd: spi-nor: add support for Gigadevice GD25D05
 | |
| +
 | |
| +Signed-off-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
 | |
| +---
 | |
| + drivers/mtd/spi-nor/spi-nor.c | 5 +++++
 | |
| + 1 file changed, 5 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/spi-nor/gigadevice.c
 | |
| ++++ b/drivers/mtd/spi-nor/gigadevice.c
 | |
| +@@ -24,6 +24,9 @@ static struct spi_nor_fixups gd25q256_fi
 | |
| + };
 | |
| + 
 | |
| + static const struct flash_info gigadevice_parts[] = {
 | |
| ++	{ "gd25q05", INFO(0xc84010, 0, 64 * 1024,  1,
 | |
| ++			  SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 | |
| ++			  SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 | |
| + 	{ "gd25q16", INFO(0xc84015, 0, 64 * 1024,  32,
 | |
| + 			  SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 | |
| + 			  SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 | |
| diff --git a/target/linux/generic/pending-5.10/483-mtd-spi-nor-add-gd25q512.patch b/target/linux/generic/pending-5.10/483-mtd-spi-nor-add-gd25q512.patch
 | |
| new file mode 100644
 | |
| index 0000000000..6f41546964
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/483-mtd-spi-nor-add-gd25q512.patch
 | |
| @@ -0,0 +1,12 @@
 | |
| +--- a/drivers/mtd/spi-nor/gigadevice.c
 | |
| ++++ b/drivers/mtd/spi-nor/gigadevice.c
 | |
| +@@ -53,6 +53,9 @@ static const struct flash_info gigadevic
 | |
| + 			   SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK |
 | |
| + 			   SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
 | |
| + 		.fixups = &gd25q256_fixups },
 | |
| ++	{ "gd25q512", INFO(0xc84020, 0, 64 * 1024, 1024,
 | |
| ++			   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 | |
| ++			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | SPI_NOR_4B_OPCODES) },
 | |
| + };
 | |
| + 
 | |
| + const struct spi_nor_manufacturer spi_nor_gigadevice = {
 | |
| diff --git a/target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch b/target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
 | |
| new file mode 100644
 | |
| index 0000000000..7c9766fa7b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/490-ubi-auto-attach-mtd-device-named-ubi-or-data-on-boot.patch
 | |
| @@ -0,0 +1,97 @@
 | |
| +From: Daniel Golle <daniel@makrotopia.org>
 | |
| +Subject: ubi: auto-attach mtd device named "ubi" or "data" on boot
 | |
| +
 | |
| +Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | |
| +---
 | |
| + drivers/mtd/ubi/build.c | 36 ++++++++++++++++++++++++++++++++++++
 | |
| + 1 file changed, 36 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/ubi/build.c
 | |
| ++++ b/drivers/mtd/ubi/build.c
 | |
| +@@ -1192,6 +1192,73 @@ static struct mtd_info * __init open_mtd
 | |
| + 	return mtd;
 | |
| + }
 | |
| + 
 | |
| ++/*
 | |
| ++ * This function tries attaching mtd partitions named either "ubi" or "data"
 | |
| ++ * during boot.
 | |
| ++ */
 | |
| ++static void __init ubi_auto_attach(void)
 | |
| ++{
 | |
| ++	int err;
 | |
| ++	struct mtd_info *mtd;
 | |
| ++	loff_t offset = 0;
 | |
| ++	size_t len;
 | |
| ++	char magic[4];
 | |
| ++
 | |
| ++	/* try attaching mtd device named "ubi" or "data" */
 | |
| ++	mtd = open_mtd_device("ubi");
 | |
| ++	if (IS_ERR(mtd))
 | |
| ++		mtd = open_mtd_device("data");
 | |
| ++
 | |
| ++	if (IS_ERR(mtd))
 | |
| ++		return;
 | |
| ++
 | |
| ++	/* get the first not bad block */
 | |
| ++	if (mtd_can_have_bb(mtd))
 | |
| ++		while (mtd_block_isbad(mtd, offset)) {
 | |
| ++			offset += mtd->erasesize;
 | |
| ++
 | |
| ++			if (offset > mtd->size) {
 | |
| ++				pr_err("UBI error: Failed to find a non-bad "
 | |
| ++				       "block on mtd%d\n", mtd->index);
 | |
| ++				goto cleanup;
 | |
| ++			}
 | |
| ++		}
 | |
| ++
 | |
| ++	/* check if the read from flash was successful */
 | |
| ++	err = mtd_read(mtd, offset, 4, &len, (void *) magic);
 | |
| ++	if ((err && !mtd_is_bitflip(err)) || len != 4) {
 | |
| ++		pr_err("UBI error: unable to read from mtd%d\n", mtd->index);
 | |
| ++		goto cleanup;
 | |
| ++	}
 | |
| ++
 | |
| ++	/* check for a valid ubi magic */
 | |
| ++	if (strncmp(magic, "UBI#", 4)) {
 | |
| ++		pr_err("UBI error: no valid UBI magic found inside mtd%d\n", mtd->index);
 | |
| ++		goto cleanup;
 | |
| ++	}
 | |
| ++
 | |
| ++	/* don't auto-add media types where UBI doesn't makes sense */
 | |
| ++	if (mtd->type != MTD_NANDFLASH &&
 | |
| ++	    mtd->type != MTD_NORFLASH &&
 | |
| ++	    mtd->type != MTD_DATAFLASH &&
 | |
| ++	    mtd->type != MTD_MLCNANDFLASH)
 | |
| ++		goto cleanup;
 | |
| ++
 | |
| ++	mutex_lock(&ubi_devices_mutex);
 | |
| ++	pr_notice("UBI: auto-attach mtd%d\n", mtd->index);
 | |
| ++	err = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 0);
 | |
| ++	mutex_unlock(&ubi_devices_mutex);
 | |
| ++	if (err < 0) {
 | |
| ++		pr_err("UBI error: cannot attach mtd%d\n", mtd->index);
 | |
| ++		goto cleanup;
 | |
| ++	}
 | |
| ++
 | |
| ++	return;
 | |
| ++
 | |
| ++cleanup:
 | |
| ++	put_mtd_device(mtd);
 | |
| ++}
 | |
| ++
 | |
| + static int __init ubi_init(void)
 | |
| + {
 | |
| + 	int err, i, k;
 | |
| +@@ -1275,6 +1342,12 @@ static int __init ubi_init(void)
 | |
| + 		}
 | |
| + 	}
 | |
| + 
 | |
| ++	/* auto-attach mtd devices only if built-in to the kernel and no ubi.mtd
 | |
| ++	 * parameter was given */
 | |
| ++	if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
 | |
| ++	    !ubi_is_module() && !mtd_devs)
 | |
| ++		ubi_auto_attach();
 | |
| ++
 | |
| + 	err = ubiblock_init();
 | |
| + 	if (err) {
 | |
| + 		pr_err("UBI error: block: cannot initialize, error %d\n", err);
 | |
| diff --git a/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a2b48fd4fc
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/491-ubi-auto-create-ubiblock-device-for-rootfs.patch
 | |
| @@ -0,0 +1,69 @@
 | |
| +From: Daniel Golle <daniel@makrotopia.org>
 | |
| +Subject: ubi: auto-create ubiblock device for rootfs
 | |
| +
 | |
| +Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | |
| +---
 | |
| + drivers/mtd/ubi/block.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 | |
| + 1 file changed, 42 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/ubi/block.c
 | |
| ++++ b/drivers/mtd/ubi/block.c
 | |
| +@@ -652,6 +652,47 @@ static void __init ubiblock_create_from_
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| ++#define UBIFS_NODE_MAGIC  0x06101831
 | |
| ++static inline int ubi_vol_is_ubifs(struct ubi_volume_desc *desc)
 | |
| ++{
 | |
| ++	int ret;
 | |
| ++	uint32_t magic_of, magic;
 | |
| ++	ret = ubi_read(desc, 0, (char *)&magic_of, 0, 4);
 | |
| ++	if (ret)
 | |
| ++		return 0;
 | |
| ++	magic = le32_to_cpu(magic_of);
 | |
| ++	return magic == UBIFS_NODE_MAGIC;
 | |
| ++}
 | |
| ++
 | |
| ++static void __init ubiblock_create_auto_rootfs(void)
 | |
| ++{
 | |
| ++	int ubi_num, ret, is_ubifs;
 | |
| ++	struct ubi_volume_desc *desc;
 | |
| ++	struct ubi_volume_info vi;
 | |
| ++
 | |
| ++	for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) {
 | |
| ++		desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY);
 | |
| ++		if (IS_ERR(desc))
 | |
| ++			desc = ubi_open_volume_nm(ubi_num, "fit", UBI_READONLY);;
 | |
| ++
 | |
| ++		if (IS_ERR(desc))
 | |
| ++			continue;
 | |
| ++
 | |
| ++		ubi_get_volume_info(desc, &vi);
 | |
| ++		is_ubifs = ubi_vol_is_ubifs(desc);
 | |
| ++		ubi_close_volume(desc);
 | |
| ++		if (is_ubifs)
 | |
| ++			break;
 | |
| ++
 | |
| ++		ret = ubiblock_create(&vi);
 | |
| ++		if (ret)
 | |
| ++			pr_err("UBI error: block: can't add '%s' volume, err=%d\n",
 | |
| ++				vi.name, ret);
 | |
| ++		/* always break if we get here */
 | |
| ++		break;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| + static void ubiblock_remove_all(void)
 | |
| + {
 | |
| + 	struct ubiblock *next;
 | |
| +@@ -684,6 +725,10 @@ int __init ubiblock_init(void)
 | |
| + 	 */
 | |
| + 	ubiblock_create_from_param();
 | |
| + 
 | |
| ++	/* auto-attach "rootfs" volume if existing and non-ubifs */
 | |
| ++	if (IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV))
 | |
| ++		ubiblock_create_auto_rootfs();
 | |
| ++
 | |
| + 	/*
 | |
| + 	 * Block devices are only created upon user requests, so we ignore
 | |
| + 	 * existing volumes.
 | |
| diff --git a/target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch b/target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch
 | |
| new file mode 100644
 | |
| index 0000000000..af65cbfa59
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/492-try-auto-mounting-ubi0-rootfs-in-init-do_mounts.c.patch
 | |
| @@ -0,0 +1,51 @@
 | |
| +From: Daniel Golle <daniel@makrotopia.org>
 | |
| +Subject: try auto-mounting ubi0:rootfs in init/do_mounts.c
 | |
| +
 | |
| +Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | |
| +---
 | |
| + init/do_mounts.c | 26 +++++++++++++++++++++++++-
 | |
| + 1 file changed, 25 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/init/do_mounts.c
 | |
| ++++ b/init/do_mounts.c
 | |
| +@@ -474,7 +474,28 @@ retry:
 | |
| + out:
 | |
| + 	put_page(page);
 | |
| + }
 | |
| +- 
 | |
| ++
 | |
| ++static int __init mount_ubi_rootfs(void)
 | |
| ++{
 | |
| ++	int flags = MS_SILENT;
 | |
| ++	int err, tried = 0;
 | |
| ++
 | |
| ++	while (tried < 2) {
 | |
| ++		err = do_mount_root("ubi0:rootfs", "ubifs", flags, \
 | |
| ++					root_mount_data);
 | |
| ++		switch (err) {
 | |
| ++			case -EACCES:
 | |
| ++				flags |= MS_RDONLY;
 | |
| ++				tried++;
 | |
| ++				break;
 | |
| ++			default:
 | |
| ++				return err;
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	return -EINVAL;
 | |
| ++}
 | |
| ++
 | |
| + #ifdef CONFIG_ROOT_NFS
 | |
| + 
 | |
| + #define NFSROOT_TIMEOUT_MIN	5
 | |
| +@@ -567,6 +588,10 @@ void __init mount_root(void)
 | |
| + 		return;
 | |
| + 	}
 | |
| + #endif
 | |
| ++#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
 | |
| ++	if (!mount_ubi_rootfs())
 | |
| ++		return;
 | |
| ++#endif
 | |
| + #ifdef CONFIG_BLOCK
 | |
| + 	{
 | |
| + 		int err = create_dev("/dev/root", ROOT_DEV);
 | |
| diff --git a/target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch b/target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2dff46807e
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/493-ubi-set-ROOT_DEV-to-ubiblock-rootfs-if-unset.patch
 | |
| @@ -0,0 +1,34 @@
 | |
| +From: Daniel Golle <daniel@makrotopia.org>
 | |
| +Subject: ubi: set ROOT_DEV to ubiblock "rootfs" if unset
 | |
| +
 | |
| +Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | |
| +---
 | |
| + drivers/mtd/ubi/block.c | 10 ++++++++++
 | |
| + 1 file changed, 10 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/ubi/block.c
 | |
| ++++ b/drivers/mtd/ubi/block.c
 | |
| +@@ -42,6 +42,7 @@
 | |
| + #include <linux/scatterlist.h>
 | |
| + #include <linux/idr.h>
 | |
| + #include <asm/div64.h>
 | |
| ++#include <linux/root_dev.h>
 | |
| + 
 | |
| + #include "ubi-media.h"
 | |
| + #include "ubi.h"
 | |
| +@@ -458,6 +459,15 @@ int ubiblock_create(struct ubi_volume_in
 | |
| + 	dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
 | |
| + 		 dev->ubi_num, dev->vol_id, vi->name);
 | |
| + 	mutex_unlock(&devices_mutex);
 | |
| ++
 | |
| ++	if (!strcmp(vi->name, "rootfs") &&
 | |
| ++	    IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
 | |
| ++	    ROOT_DEV == 0) {
 | |
| ++		pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n",
 | |
| ++			  dev->ubi_num, dev->vol_id, vi->name);
 | |
| ++		ROOT_DEV = MKDEV(gd->major, gd->first_minor);
 | |
| ++	}
 | |
| ++
 | |
| + 	return 0;
 | |
| + 
 | |
| + out_free_queue:
 | |
| diff --git a/target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..81d32ca5a5
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/494-mtd-ubi-add-EOF-marker-support.patch
 | |
| @@ -0,0 +1,60 @@
 | |
| +From: Gabor Juhos <juhosg@openwrt.org>
 | |
| +Subject: mtd: add EOF marker support to the UBI layer
 | |
| +
 | |
| +Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 | |
| +---
 | |
| + drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++---
 | |
| + drivers/mtd/ubi/ubi.h    |  1 +
 | |
| + 2 files changed, 23 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/drivers/mtd/ubi/attach.c
 | |
| ++++ b/drivers/mtd/ubi/attach.c
 | |
| +@@ -926,6 +926,13 @@ static bool vol_ignored(int vol_id)
 | |
| + #endif
 | |
| + }
 | |
| + 
 | |
| ++static bool ec_hdr_has_eof(struct ubi_ec_hdr *ech)
 | |
| ++{
 | |
| ++	return ech->padding1[0] == 'E' &&
 | |
| ++	       ech->padding1[1] == 'O' &&
 | |
| ++	       ech->padding1[2] == 'F';
 | |
| ++}
 | |
| ++
 | |
| + /**
 | |
| +  * scan_peb - scan and process UBI headers of a PEB.
 | |
| +  * @ubi: UBI device description object
 | |
| +@@ -958,9 +965,21 @@ static int scan_peb(struct ubi_device *u
 | |
| + 		return 0;
 | |
| + 	}
 | |
| + 
 | |
| +-	err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
 | |
| +-	if (err < 0)
 | |
| +-		return err;
 | |
| ++	if (!ai->eof_found) {
 | |
| ++		err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
 | |
| ++		if (err < 0)
 | |
| ++			return err;
 | |
| ++
 | |
| ++		if (ec_hdr_has_eof(ech)) {
 | |
| ++			pr_notice("UBI: EOF marker found, PEBs from %d will be erased\n",
 | |
| ++				pnum);
 | |
| ++			ai->eof_found = true;
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	if (ai->eof_found)
 | |
| ++		err = UBI_IO_FF_BITFLIPS;
 | |
| ++
 | |
| + 	switch (err) {
 | |
| + 	case 0:
 | |
| + 		break;
 | |
| +--- a/drivers/mtd/ubi/ubi.h
 | |
| ++++ b/drivers/mtd/ubi/ubi.h
 | |
| +@@ -782,6 +782,7 @@ struct ubi_attach_info {
 | |
| + 	int mean_ec;
 | |
| + 	uint64_t ec_sum;
 | |
| + 	int ec_count;
 | |
| ++	bool eof_found;
 | |
| + 	struct kmem_cache *aeb_slab_cache;
 | |
| + 	struct ubi_ec_hdr *ech;
 | |
| + 	struct ubi_vid_io_buf *vidb;
 | |
| diff --git a/target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch b/target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch
 | |
| new file mode 100644
 | |
| index 0000000000..7a7ad6b263
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/495-mtd-core-add-get_mtd_device_by_node.patch
 | |
| @@ -0,0 +1,75 @@
 | |
| +From 1bd1b740f208d1cf4071932cc51860d37266c402 Mon Sep 17 00:00:00 2001
 | |
| +From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
 | |
| +Date: Sat, 1 Sep 2018 00:30:11 +0200
 | |
| +Subject: [PATCH 495/497] mtd: core: add get_mtd_device_by_node
 | |
| +
 | |
| +Add function to retrieve a mtd device by its OF node. Since drivers can
 | |
| +assign arbitrary names to mtd devices in the absence of a label
 | |
| +property, there is no other reliable way to retrieve a mtd device for a
 | |
| +given OF node.
 | |
| +
 | |
| +Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
 | |
| +Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
 | |
| +---
 | |
| + drivers/mtd/mtdcore.c   | 38 ++++++++++++++++++++++++++++++++++++++
 | |
| + include/linux/mtd/mtd.h |  2 ++
 | |
| + 2 files changed, 40 insertions(+)
 | |
| +
 | |
| +--- a/drivers/mtd/mtdcore.c
 | |
| ++++ b/drivers/mtd/mtdcore.c
 | |
| +@@ -1053,6 +1053,44 @@ out_unlock:
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(get_mtd_device_nm);
 | |
| + 
 | |
| ++/**
 | |
| ++ *	get_mtd_device_by_node - obtain a validated handle for an MTD device
 | |
| ++ *	by of_node
 | |
| ++ *	@of_node: OF node of MTD device to open
 | |
| ++ *
 | |
| ++ *	This function returns MTD device description structure in case of
 | |
| ++ *	success and an error code in case of failure.
 | |
| ++ */
 | |
| ++struct mtd_info *get_mtd_device_by_node(const struct device_node *of_node)
 | |
| ++{
 | |
| ++	int err = -ENODEV;
 | |
| ++	struct mtd_info *mtd = NULL, *other;
 | |
| ++
 | |
| ++	mutex_lock(&mtd_table_mutex);
 | |
| ++
 | |
| ++	mtd_for_each_device(other) {
 | |
| ++		if (of_node == other->dev.of_node) {
 | |
| ++			mtd = other;
 | |
| ++			break;
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	if (!mtd)
 | |
| ++		goto out_unlock;
 | |
| ++
 | |
| ++	err = __get_mtd_device(mtd);
 | |
| ++	if (err)
 | |
| ++		goto out_unlock;
 | |
| ++
 | |
| ++	mutex_unlock(&mtd_table_mutex);
 | |
| ++	return mtd;
 | |
| ++
 | |
| ++out_unlock:
 | |
| ++	mutex_unlock(&mtd_table_mutex);
 | |
| ++	return ERR_PTR(err);
 | |
| ++}
 | |
| ++EXPORT_SYMBOL_GPL(get_mtd_device_by_node);
 | |
| ++
 | |
| + void put_mtd_device(struct mtd_info *mtd)
 | |
| + {
 | |
| + 	mutex_lock(&mtd_table_mutex);
 | |
| +--- a/include/linux/mtd/mtd.h
 | |
| ++++ b/include/linux/mtd/mtd.h
 | |
| +@@ -696,6 +696,8 @@ extern struct mtd_info *get_mtd_device(s
 | |
| + extern int __get_mtd_device(struct mtd_info *mtd);
 | |
| + extern void __put_mtd_device(struct mtd_info *mtd);
 | |
| + extern struct mtd_info *get_mtd_device_nm(const char *name);
 | |
| ++extern struct mtd_info *get_mtd_device_by_node(
 | |
| ++		const struct device_node *of_node);
 | |
| + extern void put_mtd_device(struct mtd_info *mtd);
 | |
| + 
 | |
| + static inline uint64_t mtdpart_get_offset(const struct mtd_info *mtd)
 | |
| diff --git a/target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch b/target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch
 | |
| new file mode 100644
 | |
| index 0000000000..01f3b9ec2d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/496-dt-bindings-add-bindings-for-mtd-concat-devices.patch
 | |
| @@ -0,0 +1,52 @@
 | |
| +From 5734c6669fba7ddb5ef491ccff7159d15dba0b59 Mon Sep 17 00:00:00 2001
 | |
| +From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
 | |
| +Date: Wed, 5 Sep 2018 01:32:51 +0200
 | |
| +Subject: [PATCH 496/497] dt-bindings: add bindings for mtd-concat devices
 | |
| +
 | |
| +Document virtual mtd-concat device bindings.
 | |
| +
 | |
| +Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
 | |
| +---
 | |
| + .../devicetree/bindings/mtd/mtd-concat.txt    | 36 +++++++++++++++++++
 | |
| + 1 file changed, 36 insertions(+)
 | |
| + create mode 100644 Documentation/devicetree/bindings/mtd/mtd-concat.txt
 | |
| +
 | |
| +--- /dev/null
 | |
| ++++ b/Documentation/devicetree/bindings/mtd/mtd-concat.txt
 | |
| +@@ -0,0 +1,36 @@
 | |
| ++Virtual MTD concat device
 | |
| ++
 | |
| ++Requires properties:
 | |
| ++- devices: list of phandles to mtd nodes that should be concatenated
 | |
| ++
 | |
| ++Example:
 | |
| ++
 | |
| ++&spi {
 | |
| ++	flash0: flash@0 {
 | |
| ++		...
 | |
| ++	};
 | |
| ++	flash1: flash@1 {
 | |
| ++		...
 | |
| ++	};
 | |
| ++};
 | |
| ++
 | |
| ++flash {
 | |
| ++	compatible = "mtd-concat";
 | |
| ++
 | |
| ++	devices = <&flash0 &flash1>;
 | |
| ++
 | |
| ++	partitions {
 | |
| ++		compatible = "fixed-partitions";
 | |
| ++
 | |
| ++		partition@0 {
 | |
| ++			label = "boot";
 | |
| ++			reg = <0x0000000 0x0040000>;
 | |
| ++			read-only;
 | |
| ++		};
 | |
| ++
 | |
| ++		partition@40000 {
 | |
| ++			label = "firmware";
 | |
| ++			reg = <0x0040000 0x1fc0000>;
 | |
| ++		};
 | |
| ++	}
 | |
| ++}
 | |
| diff --git a/target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch b/target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch
 | |
| new file mode 100644
 | |
| index 0000000000..058cab09e5
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/497-mtd-mtdconcat-add-dt-driver-for-concat-devices.patch
 | |
| @@ -0,0 +1,216 @@
 | |
| +From e53f712d8eac71f54399b61038ccf87d2cee99d7 Mon Sep 17 00:00:00 2001
 | |
| +From: Bernhard Frauendienst <kernel@nospam.obeliks.de>
 | |
| +Date: Sat, 25 Aug 2018 12:35:22 +0200
 | |
| +Subject: [PATCH 497/497] mtd: mtdconcat: add dt driver for concat devices
 | |
| +
 | |
| +Some mtd drivers like physmap variants have support for concatenating
 | |
| +multiple mtd devices, but there is no generic way to define such a
 | |
| +concat device from within the device tree.
 | |
| +
 | |
| +This is useful for some SoC boards that use multiple flash chips as
 | |
| +memory banks of a single mtd device, with partitions spanning chip
 | |
| +borders.
 | |
| +
 | |
| +This commit adds a driver for creating virtual mtd-concat devices. They
 | |
| +must have a compatible = "mtd-concat" line, and define a list of devices
 | |
| +to concat in the 'devices' property, for example:
 | |
| +
 | |
| +flash {
 | |
| +  compatible = "mtd-concat";
 | |
| +
 | |
| +  devices = <&flash0 &flash1>;
 | |
| +
 | |
| +  partitions {
 | |
| +    ...
 | |
| +  };
 | |
| +};
 | |
| +
 | |
| +The driver is added to the very end of the mtd Makefile to increase the
 | |
| +likelyhood of all child devices already being loaded at the time of
 | |
| +probing, preventing unnecessary deferred probes.
 | |
| +
 | |
| +Signed-off-by: Bernhard Frauendienst <kernel@nospam.obeliks.de>
 | |
| +---
 | |
| + drivers/mtd/Kconfig                 |   2 +
 | |
| + drivers/mtd/Makefile                |   3 +
 | |
| + drivers/mtd/composite/Kconfig       |  12 +++
 | |
| + drivers/mtd/composite/Makefile      |   6 ++
 | |
| + drivers/mtd/composite/virt_concat.c | 128 ++++++++++++++++++++++++++++
 | |
| + 5 files changed, 151 insertions(+)
 | |
| + create mode 100644 drivers/mtd/composite/Kconfig
 | |
| + create mode 100644 drivers/mtd/composite/Makefile
 | |
| + create mode 100644 drivers/mtd/composite/virt_concat.c
 | |
| +
 | |
| +--- a/drivers/mtd/Kconfig
 | |
| ++++ b/drivers/mtd/Kconfig
 | |
| +@@ -238,4 +238,6 @@ source "drivers/mtd/ubi/Kconfig"
 | |
| + 
 | |
| + source "drivers/mtd/hyperbus/Kconfig"
 | |
| + 
 | |
| ++source "drivers/mtd/composite/Kconfig"
 | |
| ++
 | |
| + endif # MTD
 | |
| +--- a/drivers/mtd/Makefile
 | |
| ++++ b/drivers/mtd/Makefile
 | |
| +@@ -33,3 +33,6 @@ obj-y		+= chips/ lpddr/ maps/ devices/ n
 | |
| + obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor/
 | |
| + obj-$(CONFIG_MTD_UBI)		+= ubi/
 | |
| + obj-$(CONFIG_MTD_HYPERBUS)	+= hyperbus/
 | |
| ++
 | |
| ++# Composite drivers must be loaded last
 | |
| ++obj-y				+= composite/
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/composite/Kconfig
 | |
| +@@ -0,0 +1,12 @@
 | |
| ++menu "Composite MTD device drivers"
 | |
| ++	depends on MTD!=n
 | |
| ++
 | |
| ++config MTD_VIRT_CONCAT
 | |
| ++	tristate "Virtual concat MTD device"
 | |
| ++	help
 | |
| ++	  This driver allows creation of a virtual MTD concat device, which
 | |
| ++	  concatenates multiple underlying MTD devices to a single device.
 | |
| ++	  This is required by some SoC boards where multiple memory banks are
 | |
| ++	  used as one device with partitions spanning across device boundaries.
 | |
| ++
 | |
| ++endmenu
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/composite/Makefile
 | |
| +@@ -0,0 +1,6 @@
 | |
| ++# SPDX-License-Identifier: GPL-2.0
 | |
| ++#
 | |
| ++# linux/drivers/mtd/composite/Makefile
 | |
| ++#
 | |
| ++
 | |
| ++obj-$(CONFIG_MTD_VIRT_CONCAT)   += virt_concat.o
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/mtd/composite/virt_concat.c
 | |
| +@@ -0,0 +1,128 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0+
 | |
| ++/*
 | |
| ++ * Virtual concat MTD device driver
 | |
| ++ *
 | |
| ++ * Copyright (C) 2018 Bernhard Frauendienst
 | |
| ++ * Author: Bernhard Frauendienst, kernel@nospam.obeliks.de
 | |
| ++ */
 | |
| ++
 | |
| ++#include <linux/module.h>
 | |
| ++#include <linux/device.h>
 | |
| ++#include <linux/mtd/concat.h>
 | |
| ++#include <linux/mtd/mtd.h>
 | |
| ++#include <linux/mtd/partitions.h>
 | |
| ++#include <linux/of.h>
 | |
| ++#include <linux/of_platform.h>
 | |
| ++#include <linux/slab.h>
 | |
| ++
 | |
| ++/*
 | |
| ++ * struct of_virt_concat - platform device driver data.
 | |
| ++ * @cmtd the final mtd_concat device
 | |
| ++ * @num_devices the number of devices in @devices
 | |
| ++ * @devices points to an array of devices already loaded
 | |
| ++ */
 | |
| ++struct of_virt_concat {
 | |
| ++	struct mtd_info	*cmtd;
 | |
| ++	int num_devices;
 | |
| ++	struct mtd_info	**devices;
 | |
| ++};
 | |
| ++
 | |
| ++static int virt_concat_remove(struct platform_device *pdev)
 | |
| ++{
 | |
| ++	struct of_virt_concat *info;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	info = platform_get_drvdata(pdev);
 | |
| ++	if (!info)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	// unset data for when this is called after a probe error
 | |
| ++	platform_set_drvdata(pdev, NULL);
 | |
| ++
 | |
| ++	if (info->cmtd) {
 | |
| ++		mtd_device_unregister(info->cmtd);
 | |
| ++		mtd_concat_destroy(info->cmtd);
 | |
| ++	}
 | |
| ++
 | |
| ++	if (info->devices) {
 | |
| ++		for (i = 0; i < info->num_devices; i++)
 | |
| ++			put_mtd_device(info->devices[i]);
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int virt_concat_probe(struct platform_device *pdev)
 | |
| ++{
 | |
| ++	struct device_node *node = pdev->dev.of_node;
 | |
| ++	struct of_phandle_iterator it;
 | |
| ++	struct of_virt_concat *info;
 | |
| ++	struct mtd_info *mtd;
 | |
| ++	int err = 0, count;
 | |
| ++
 | |
| ++	count = of_count_phandle_with_args(node, "devices", NULL);
 | |
| ++	if (count <= 0)
 | |
| ++		return -EINVAL;
 | |
| ++
 | |
| ++	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 | |
| ++	if (!info)
 | |
| ++		return -ENOMEM;
 | |
| ++	info->devices = devm_kcalloc(&pdev->dev, count,
 | |
| ++				     sizeof(*(info->devices)), GFP_KERNEL);
 | |
| ++	if (!info->devices) {
 | |
| ++		err = -ENOMEM;
 | |
| ++		goto err_remove;
 | |
| ++	}
 | |
| ++
 | |
| ++	platform_set_drvdata(pdev, info);
 | |
| ++
 | |
| ++	of_for_each_phandle(&it, err, node, "devices", NULL, 0) {
 | |
| ++		mtd = get_mtd_device_by_node(it.node);
 | |
| ++		if (IS_ERR(mtd)) {
 | |
| ++			of_node_put(it.node);
 | |
| ++			err = -EPROBE_DEFER;
 | |
| ++			goto err_remove;
 | |
| ++		}
 | |
| ++
 | |
| ++		info->devices[info->num_devices++] = mtd;
 | |
| ++	}
 | |
| ++
 | |
| ++	info->cmtd = mtd_concat_create(info->devices, info->num_devices,
 | |
| ++				       dev_name(&pdev->dev));
 | |
| ++	if (!info->cmtd) {
 | |
| ++		err = -ENXIO;
 | |
| ++		goto err_remove;
 | |
| ++	}
 | |
| ++
 | |
| ++	info->cmtd->dev.parent = &pdev->dev;
 | |
| ++	mtd_set_of_node(info->cmtd, node);
 | |
| ++	mtd_device_register(info->cmtd, NULL, 0);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++
 | |
| ++err_remove:
 | |
| ++	virt_concat_remove(pdev);
 | |
| ++
 | |
| ++	return err;
 | |
| ++}
 | |
| ++
 | |
| ++static const struct of_device_id virt_concat_of_match[] = {
 | |
| ++	{ .compatible = "mtd-concat", },
 | |
| ++	{ /* sentinel */ }
 | |
| ++};
 | |
| ++MODULE_DEVICE_TABLE(of, virt_concat_of_match);
 | |
| ++
 | |
| ++static struct platform_driver virt_concat_driver = {
 | |
| ++	.probe = virt_concat_probe,
 | |
| ++	.remove = virt_concat_remove,
 | |
| ++	.driver	 = {
 | |
| ++		.name   = "virt-mtdconcat",
 | |
| ++		.of_match_table = virt_concat_of_match,
 | |
| ++	},
 | |
| ++};
 | |
| ++
 | |
| ++module_platform_driver(virt_concat_driver);
 | |
| ++
 | |
| ++MODULE_LICENSE("GPL v2");
 | |
| ++MODULE_AUTHOR("Bernhard Frauendienst <kernel@nospam.obeliks.de>");
 | |
| ++MODULE_DESCRIPTION("Virtual concat MTD device driver");
 | |
| diff --git a/target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch b/target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch
 | |
| new file mode 100644
 | |
| index 0000000000..9aad0f3e6c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/498-mtd-mtdconcat-select-readwrite-function.patch
 | |
| @@ -0,0 +1,24 @@
 | |
| +--- a/drivers/mtd/mtdconcat.c
 | |
| ++++ b/drivers/mtd/mtdconcat.c
 | |
| +@@ -683,8 +683,12 @@ struct mtd_info *mtd_concat_create(struc
 | |
| + 		concat->mtd._writev = concat_writev;
 | |
| + 	if (subdev[0]->_read_oob)
 | |
| + 		concat->mtd._read_oob = concat_read_oob;
 | |
| ++	else
 | |
| ++		concat->mtd._read = concat_read;
 | |
| + 	if (subdev[0]->_write_oob)
 | |
| + 		concat->mtd._write_oob = concat_write_oob;
 | |
| ++	else
 | |
| ++		concat->mtd._write = concat_write;
 | |
| + 	if (subdev[0]->_block_isbad)
 | |
| + 		concat->mtd._block_isbad = concat_block_isbad;
 | |
| + 	if (subdev[0]->_block_markbad)
 | |
| +@@ -744,8 +748,6 @@ struct mtd_info *mtd_concat_create(struc
 | |
| + 	concat->mtd.name = name;
 | |
| + 
 | |
| + 	concat->mtd._erase = concat_erase;
 | |
| +-	concat->mtd._read = concat_read;
 | |
| +-	concat->mtd._write = concat_write;
 | |
| + 	concat->mtd._sync = concat_sync;
 | |
| + 	concat->mtd._lock = concat_lock;
 | |
| + 	concat->mtd._unlock = concat_unlock;
 | |
| diff --git a/target/linux/generic/pending-5.10/499-mtd-don-t-lock-when-recursively-deleting-partitions.patch b/target/linux/generic/pending-5.10/499-mtd-don-t-lock-when-recursively-deleting-partitions.patch
 | |
| new file mode 100644
 | |
| index 0000000000..505131b684
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/499-mtd-don-t-lock-when-recursively-deleting-partitions.patch
 | |
| @@ -0,0 +1,24 @@
 | |
| +From: David Bauer <mail@david-bauer.net>
 | |
| +Date: Wed, 17 Feb 2021 03:21:39 +0100
 | |
| +Subject: [PATCH] mtd: don't lock when recursively deleting partitions
 | |
| +
 | |
| +When recursively deleting partitions, don't acquire the masters
 | |
| +partition lock twice. Otherwise the process endy up in a deadlocked
 | |
| +state.
 | |
| +
 | |
| +Signed-off-by: David Bauer <mail@david-bauer.net>
 | |
| +---
 | |
| + drivers/mtd/mtdpart.c | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/drivers/mtd/mtdpart.c
 | |
| ++++ b/drivers/mtd/mtdpart.c
 | |
| +@@ -474,7 +474,7 @@ static int __del_mtd_partitions(struct m
 | |
| + 
 | |
| + 	list_for_each_entry_safe(child, next, &mtd->partitions, part.node) {
 | |
| + 		if (mtd_has_partitions(child))
 | |
| +-			del_mtd_partitions(child);
 | |
| ++			__del_mtd_partitions(child);
 | |
| + 
 | |
| + 		pr_info("Deleting %s MTD partition\n", child->name);
 | |
| + 		ret = del_mtd_device(child);
 | |
| diff --git a/target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch b/target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0a5a3aae5d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/500-fs_cdrom_dependencies.patch
 | |
| @@ -0,0 +1,40 @@
 | |
| +--- a/fs/hfs/Kconfig
 | |
| ++++ b/fs/hfs/Kconfig
 | |
| +@@ -2,6 +2,7 @@
 | |
| + config HFS_FS
 | |
| + 	tristate "Apple Macintosh file system support"
 | |
| + 	depends on BLOCK
 | |
| ++	select CDROM
 | |
| + 	select NLS
 | |
| + 	help
 | |
| + 	  If you say Y here, you will be able to mount Macintosh-formatted
 | |
| +--- a/fs/hfsplus/Kconfig
 | |
| ++++ b/fs/hfsplus/Kconfig
 | |
| +@@ -2,6 +2,7 @@
 | |
| + config HFSPLUS_FS
 | |
| + 	tristate "Apple Extended HFS file system support"
 | |
| + 	depends on BLOCK
 | |
| ++	select CDROM
 | |
| + 	select NLS
 | |
| + 	select NLS_UTF8
 | |
| + 	help
 | |
| +--- a/fs/isofs/Kconfig
 | |
| ++++ b/fs/isofs/Kconfig
 | |
| +@@ -1,6 +1,7 @@
 | |
| + # SPDX-License-Identifier: GPL-2.0-only
 | |
| + config ISO9660_FS
 | |
| + 	tristate "ISO 9660 CDROM file system support"
 | |
| ++	select CDROM
 | |
| + 	help
 | |
| + 	  This is the standard file system used on CD-ROMs.  It was previously
 | |
| + 	  known as "High Sierra File System" and is called "hsfs" on other
 | |
| +--- a/fs/udf/Kconfig
 | |
| ++++ b/fs/udf/Kconfig
 | |
| +@@ -1,6 +1,7 @@
 | |
| + # SPDX-License-Identifier: GPL-2.0-only
 | |
| + config UDF_FS
 | |
| + 	tristate "UDF file system support"
 | |
| ++	select CDROM
 | |
| + 	select CRC_ITU_T
 | |
| + 	select NLS
 | |
| + 	help
 | |
| diff --git a/target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch b/target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1bccb30a69
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/530-jffs2_make_lzma_available.patch
 | |
| @@ -0,0 +1,5180 @@
 | |
| +From: Alexandros C. Couloumbis <alex@ozo.com>
 | |
| +Subject: fs: add jffs2/lzma support (not activated by default yet)
 | |
| +
 | |
| +lede-commit: c2c88d315fa0e881f8b19da07b62859b915b11b2
 | |
| +Signed-off-by: Alexandros C. Couloumbis <alex@ozo.com>
 | |
| +---
 | |
| + fs/jffs2/Kconfig             |    9 +
 | |
| + fs/jffs2/Makefile            |    3 +
 | |
| + fs/jffs2/compr.c             |    6 +
 | |
| + fs/jffs2/compr.h             |   10 +-
 | |
| + fs/jffs2/compr_lzma.c        |  128 +++
 | |
| + fs/jffs2/super.c             |   33 +-
 | |
| + include/linux/lzma.h         |   62 ++
 | |
| + include/linux/lzma/LzFind.h  |  115 +++
 | |
| + include/linux/lzma/LzHash.h  |   54 +
 | |
| + include/linux/lzma/LzmaDec.h |  231 +++++
 | |
| + include/linux/lzma/LzmaEnc.h |   80 ++
 | |
| + include/linux/lzma/Types.h   |  226 +++++
 | |
| + include/uapi/linux/jffs2.h   |    1 +
 | |
| + lib/Kconfig                  |    6 +
 | |
| + lib/Makefile                 |   12 +
 | |
| + lib/lzma/LzFind.c            |  761 ++++++++++++++
 | |
| + lib/lzma/LzmaDec.c           |  999 +++++++++++++++++++
 | |
| + lib/lzma/LzmaEnc.c           | 2271 ++++++++++++++++++++++++++++++++++++++++++
 | |
| + lib/lzma/Makefile            |    7 +
 | |
| + 19 files changed, 5008 insertions(+), 6 deletions(-)
 | |
| + create mode 100644 fs/jffs2/compr_lzma.c
 | |
| + create mode 100644 include/linux/lzma.h
 | |
| + create mode 100644 include/linux/lzma/LzFind.h
 | |
| + create mode 100644 include/linux/lzma/LzHash.h
 | |
| + create mode 100644 include/linux/lzma/LzmaDec.h
 | |
| + create mode 100644 include/linux/lzma/LzmaEnc.h
 | |
| + create mode 100644 include/linux/lzma/Types.h
 | |
| + create mode 100644 lib/lzma/LzFind.c
 | |
| + create mode 100644 lib/lzma/LzmaDec.c
 | |
| + create mode 100644 lib/lzma/LzmaEnc.c
 | |
| + create mode 100644 lib/lzma/Makefile
 | |
| +
 | |
| +--- a/fs/jffs2/Kconfig
 | |
| ++++ b/fs/jffs2/Kconfig
 | |
| +@@ -136,6 +136,15 @@ config JFFS2_LZO
 | |
| + 	  This feature was added in July, 2007. Say 'N' if you need
 | |
| + 	  compatibility with older bootloaders or kernels.
 | |
| + 
 | |
| ++config JFFS2_LZMA
 | |
| ++	bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS
 | |
| ++	select LZMA_COMPRESS
 | |
| ++	select LZMA_DECOMPRESS
 | |
| ++	depends on JFFS2_FS
 | |
| ++	default n
 | |
| ++	help
 | |
| ++	  JFFS2 wrapper to the LZMA C SDK
 | |
| ++
 | |
| + config JFFS2_RTIME
 | |
| + 	bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
 | |
| + 	depends on JFFS2_FS
 | |
| +--- a/fs/jffs2/Makefile
 | |
| ++++ b/fs/jffs2/Makefile
 | |
| +@@ -19,4 +19,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN)	+= compr_rub
 | |
| + jffs2-$(CONFIG_JFFS2_RTIME)	+= compr_rtime.o
 | |
| + jffs2-$(CONFIG_JFFS2_ZLIB)	+= compr_zlib.o
 | |
| + jffs2-$(CONFIG_JFFS2_LZO)	+= compr_lzo.o
 | |
| ++jffs2-$(CONFIG_JFFS2_LZMA)	+= compr_lzma.o
 | |
| + jffs2-$(CONFIG_JFFS2_SUMMARY)   += summary.o
 | |
| ++
 | |
| ++CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma
 | |
| +--- a/fs/jffs2/compr.c
 | |
| ++++ b/fs/jffs2/compr.c
 | |
| +@@ -378,6 +378,9 @@ int __init jffs2_compressors_init(void)
 | |
| + #ifdef CONFIG_JFFS2_LZO
 | |
| + 	jffs2_lzo_init();
 | |
| + #endif
 | |
| ++#ifdef CONFIG_JFFS2_LZMA
 | |
| ++	jffs2_lzma_init();
 | |
| ++#endif
 | |
| + /* Setting default compression mode */
 | |
| + #ifdef CONFIG_JFFS2_CMODE_NONE
 | |
| + 	jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
 | |
| +@@ -401,6 +404,9 @@ int __init jffs2_compressors_init(void)
 | |
| + int jffs2_compressors_exit(void)
 | |
| + {
 | |
| + /* Unregistering compressors */
 | |
| ++#ifdef CONFIG_JFFS2_LZMA
 | |
| ++	jffs2_lzma_exit();
 | |
| ++#endif
 | |
| + #ifdef CONFIG_JFFS2_LZO
 | |
| + 	jffs2_lzo_exit();
 | |
| + #endif
 | |
| +--- a/fs/jffs2/compr.h
 | |
| ++++ b/fs/jffs2/compr.h
 | |
| +@@ -29,9 +29,9 @@
 | |
| + #define JFFS2_DYNRUBIN_PRIORITY  20
 | |
| + #define JFFS2_LZARI_PRIORITY     30
 | |
| + #define JFFS2_RTIME_PRIORITY     50
 | |
| +-#define JFFS2_ZLIB_PRIORITY      60
 | |
| +-#define JFFS2_LZO_PRIORITY       80
 | |
| +-
 | |
| ++#define JFFS2_LZMA_PRIORITY      70
 | |
| ++#define JFFS2_ZLIB_PRIORITY      80
 | |
| ++#define JFFS2_LZO_PRIORITY       90
 | |
| + 
 | |
| + #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
 | |
| + #define JFFS2_DYNRUBIN_DISABLED  /*	   for decompression */
 | |
| +@@ -101,5 +101,9 @@ void jffs2_zlib_exit(void);
 | |
| + int jffs2_lzo_init(void);
 | |
| + void jffs2_lzo_exit(void);
 | |
| + #endif
 | |
| ++#ifdef CONFIG_JFFS2_LZMA
 | |
| ++int jffs2_lzma_init(void);
 | |
| ++void jffs2_lzma_exit(void);
 | |
| ++#endif
 | |
| + 
 | |
| + #endif /* __JFFS2_COMPR_H__ */
 | |
| +--- /dev/null
 | |
| ++++ b/fs/jffs2/compr_lzma.c
 | |
| +@@ -0,0 +1,128 @@
 | |
| ++/*
 | |
| ++ * JFFS2 -- Journalling Flash File System, Version 2.
 | |
| ++ *
 | |
| ++ * For licensing information, see the file 'LICENCE' in this directory.
 | |
| ++ *
 | |
| ++ * JFFS2 wrapper to the LZMA C SDK
 | |
| ++ *
 | |
| ++ */
 | |
| ++
 | |
| ++#include <linux/lzma.h>
 | |
| ++#include "compr.h"
 | |
| ++
 | |
| ++#ifdef __KERNEL__
 | |
| ++	static DEFINE_MUTEX(deflate_mutex);
 | |
| ++#endif
 | |
| ++
 | |
| ++CLzmaEncHandle *p;
 | |
| ++Byte propsEncoded[LZMA_PROPS_SIZE];
 | |
| ++SizeT propsSize = sizeof(propsEncoded);
 | |
| ++
 | |
| ++STATIC void lzma_free_workspace(void)
 | |
| ++{
 | |
| ++	LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc);
 | |
| ++}
 | |
| ++
 | |
| ++STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props)
 | |
| ++{
 | |
| ++	if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL)
 | |
| ++	{
 | |
| ++		PRINT_ERROR("Failed to allocate lzma deflate workspace\n");
 | |
| ++		return -ENOMEM;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (LzmaEnc_SetProps(p, props) != SZ_OK)
 | |
| ++	{
 | |
| ++		lzma_free_workspace();
 | |
| ++		return -1;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK)
 | |
| ++	{
 | |
| ++		lzma_free_workspace();
 | |
| ++		return -1;
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out,
 | |
| ++			      uint32_t *sourcelen, uint32_t *dstlen)
 | |
| ++{
 | |
| ++	SizeT compress_size = (SizeT)(*dstlen);
 | |
| ++	int ret;
 | |
| ++
 | |
| ++	#ifdef __KERNEL__
 | |
| ++		mutex_lock(&deflate_mutex);
 | |
| ++	#endif
 | |
| ++
 | |
| ++	ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen,
 | |
| ++		0, NULL, &lzma_alloc, &lzma_alloc);
 | |
| ++
 | |
| ++	#ifdef __KERNEL__
 | |
| ++		mutex_unlock(&deflate_mutex);
 | |
| ++	#endif
 | |
| ++
 | |
| ++	if (ret != SZ_OK)
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	*dstlen = (uint32_t)compress_size;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out,
 | |
| ++				 uint32_t srclen, uint32_t destlen)
 | |
| ++{
 | |
| ++	int ret;
 | |
| ++	SizeT dl = (SizeT)destlen;
 | |
| ++	SizeT sl = (SizeT)srclen;
 | |
| ++	ELzmaStatus status;
 | |
| ++
 | |
| ++	ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded,
 | |
| ++		propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc);
 | |
| ++
 | |
| ++	if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen)
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static struct jffs2_compressor jffs2_lzma_comp = {
 | |
| ++	.priority = JFFS2_LZMA_PRIORITY,
 | |
| ++	.name = "lzma",
 | |
| ++	.compr = JFFS2_COMPR_LZMA,
 | |
| ++	.compress = &jffs2_lzma_compress,
 | |
| ++	.decompress = &jffs2_lzma_decompress,
 | |
| ++	.disabled = 0,
 | |
| ++};
 | |
| ++
 | |
| ++int INIT jffs2_lzma_init(void)
 | |
| ++{
 | |
| ++	int ret;
 | |
| ++	CLzmaEncProps props;
 | |
| ++	LzmaEncProps_Init(&props);
 | |
| ++
 | |
| ++	props.dictSize = LZMA_BEST_DICT(0x2000);
 | |
| ++	props.level = LZMA_BEST_LEVEL;
 | |
| ++	props.lc = LZMA_BEST_LC;
 | |
| ++	props.lp = LZMA_BEST_LP;
 | |
| ++	props.pb = LZMA_BEST_PB;
 | |
| ++	props.fb = LZMA_BEST_FB;
 | |
| ++
 | |
| ++	ret = lzma_alloc_workspace(&props);
 | |
| ++	if (ret < 0)
 | |
| ++		return ret;
 | |
| ++
 | |
| ++	ret = jffs2_register_compressor(&jffs2_lzma_comp);
 | |
| ++	if (ret)
 | |
| ++		lzma_free_workspace();
 | |
| ++
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++
 | |
| ++void jffs2_lzma_exit(void)
 | |
| ++{
 | |
| ++	jffs2_unregister_compressor(&jffs2_lzma_comp);
 | |
| ++	lzma_free_workspace();
 | |
| ++}
 | |
| +--- a/fs/jffs2/super.c
 | |
| ++++ b/fs/jffs2/super.c
 | |
| +@@ -374,14 +374,41 @@ static int __init init_jffs2_fs(void)
 | |
| + 	BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
 | |
| + 	BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
 | |
| + 
 | |
| +-	pr_info("version 2.2."
 | |
| ++	pr_info("version 2.2"
 | |
| + #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
 | |
| + 	       " (NAND)"
 | |
| + #endif
 | |
| + #ifdef CONFIG_JFFS2_SUMMARY
 | |
| +-	       " (SUMMARY) "
 | |
| ++	       " (SUMMARY)"
 | |
| + #endif
 | |
| +-	       " © 2001-2006 Red Hat, Inc.\n");
 | |
| ++#ifdef CONFIG_JFFS2_ZLIB
 | |
| ++	       " (ZLIB)"
 | |
| ++#endif
 | |
| ++#ifdef CONFIG_JFFS2_LZO
 | |
| ++	       " (LZO)"
 | |
| ++#endif
 | |
| ++#ifdef CONFIG_JFFS2_LZMA
 | |
| ++	       " (LZMA)"
 | |
| ++#endif
 | |
| ++#ifdef CONFIG_JFFS2_RTIME
 | |
| ++	       " (RTIME)"
 | |
| ++#endif
 | |
| ++#ifdef CONFIG_JFFS2_RUBIN
 | |
| ++	       " (RUBIN)"
 | |
| ++#endif
 | |
| ++#ifdef  CONFIG_JFFS2_CMODE_NONE
 | |
| ++	       " (CMODE_NONE)"
 | |
| ++#endif
 | |
| ++#ifdef CONFIG_JFFS2_CMODE_PRIORITY
 | |
| ++	       " (CMODE_PRIORITY)"
 | |
| ++#endif
 | |
| ++#ifdef CONFIG_JFFS2_CMODE_SIZE
 | |
| ++	       " (CMODE_SIZE)"
 | |
| ++#endif
 | |
| ++#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO
 | |
| ++	       " (CMODE_FAVOURLZO)"
 | |
| ++#endif
 | |
| ++	       " (c) 2001-2006 Red Hat, Inc.\n");
 | |
| + 
 | |
| + 	jffs2_inode_cachep = kmem_cache_create("jffs2_i",
 | |
| + 					     sizeof(struct jffs2_inode_info),
 | |
| +--- /dev/null
 | |
| ++++ b/include/linux/lzma.h
 | |
| +@@ -0,0 +1,62 @@
 | |
| ++#ifndef __LZMA_H__
 | |
| ++#define __LZMA_H__
 | |
| ++
 | |
| ++#ifdef __KERNEL__
 | |
| ++	#include <linux/kernel.h>
 | |
| ++	#include <linux/sched.h>
 | |
| ++	#include <linux/slab.h>
 | |
| ++	#include <linux/vmalloc.h>
 | |
| ++	#include <linux/init.h>
 | |
| ++	#define LZMA_MALLOC vmalloc
 | |
| ++	#define LZMA_FREE vfree
 | |
| ++	#define PRINT_ERROR(msg) printk(KERN_WARNING #msg)
 | |
| ++	#define INIT __init
 | |
| ++	#define STATIC static
 | |
| ++#else
 | |
| ++	#include <stdint.h>
 | |
| ++	#include <stdlib.h>
 | |
| ++	#include <stdio.h>
 | |
| ++	#include <unistd.h>
 | |
| ++	#include <string.h>
 | |
| ++	#include <asm/types.h>
 | |
| ++	#include <errno.h>
 | |
| ++	#include <linux/jffs2.h>
 | |
| ++	#ifndef PAGE_SIZE
 | |
| ++		extern int page_size;
 | |
| ++		#define PAGE_SIZE page_size
 | |
| ++	#endif
 | |
| ++	#define LZMA_MALLOC malloc
 | |
| ++	#define LZMA_FREE free
 | |
| ++	#define PRINT_ERROR(msg) fprintf(stderr, msg)
 | |
| ++	#define INIT
 | |
| ++	#define STATIC
 | |
| ++#endif
 | |
| ++
 | |
| ++#include "lzma/LzmaDec.h"
 | |
| ++#include "lzma/LzmaEnc.h"
 | |
| ++
 | |
| ++#define LZMA_BEST_LEVEL (9)
 | |
| ++#define LZMA_BEST_LC    (0)
 | |
| ++#define LZMA_BEST_LP    (0)
 | |
| ++#define LZMA_BEST_PB    (0)
 | |
| ++#define LZMA_BEST_FB  (273)
 | |
| ++
 | |
| ++#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2)
 | |
| ++
 | |
| ++static void *p_lzma_malloc(void *p, size_t size)
 | |
| ++{
 | |
| ++	if (size == 0)
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	return LZMA_MALLOC(size);
 | |
| ++}
 | |
| ++
 | |
| ++static void p_lzma_free(void *p, void *address)
 | |
| ++{
 | |
| ++	if (address != NULL)
 | |
| ++		LZMA_FREE(address);
 | |
| ++}
 | |
| ++
 | |
| ++static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free};
 | |
| ++
 | |
| ++#endif
 | |
| +--- /dev/null
 | |
| ++++ b/include/linux/lzma/LzFind.h
 | |
| +@@ -0,0 +1,115 @@
 | |
| ++/* LzFind.h -- Match finder for LZ algorithms
 | |
| ++2009-04-22 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#ifndef __LZ_FIND_H
 | |
| ++#define __LZ_FIND_H
 | |
| ++
 | |
| ++#include "Types.h"
 | |
| ++
 | |
| ++#ifdef __cplusplus
 | |
| ++extern "C" {
 | |
| ++#endif
 | |
| ++
 | |
| ++typedef UInt32 CLzRef;
 | |
| ++
 | |
| ++typedef struct _CMatchFinder
 | |
| ++{
 | |
| ++  Byte *buffer;
 | |
| ++  UInt32 pos;
 | |
| ++  UInt32 posLimit;
 | |
| ++  UInt32 streamPos;
 | |
| ++  UInt32 lenLimit;
 | |
| ++
 | |
| ++  UInt32 cyclicBufferPos;
 | |
| ++  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
 | |
| ++
 | |
| ++  UInt32 matchMaxLen;
 | |
| ++  CLzRef *hash;
 | |
| ++  CLzRef *son;
 | |
| ++  UInt32 hashMask;
 | |
| ++  UInt32 cutValue;
 | |
| ++
 | |
| ++  Byte *bufferBase;
 | |
| ++  ISeqInStream *stream;
 | |
| ++  int streamEndWasReached;
 | |
| ++
 | |
| ++  UInt32 blockSize;
 | |
| ++  UInt32 keepSizeBefore;
 | |
| ++  UInt32 keepSizeAfter;
 | |
| ++
 | |
| ++  UInt32 numHashBytes;
 | |
| ++  int directInput;
 | |
| ++  size_t directInputRem;
 | |
| ++  int btMode;
 | |
| ++  int bigHash;
 | |
| ++  UInt32 historySize;
 | |
| ++  UInt32 fixedHashSize;
 | |
| ++  UInt32 hashSizeSum;
 | |
| ++  UInt32 numSons;
 | |
| ++  SRes result;
 | |
| ++  UInt32 crc[256];
 | |
| ++} CMatchFinder;
 | |
| ++
 | |
| ++#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
 | |
| ++#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
 | |
| ++
 | |
| ++#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
 | |
| ++
 | |
| ++int MatchFinder_NeedMove(CMatchFinder *p);
 | |
| ++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
 | |
| ++void MatchFinder_MoveBlock(CMatchFinder *p);
 | |
| ++void MatchFinder_ReadIfRequired(CMatchFinder *p);
 | |
| ++
 | |
| ++void MatchFinder_Construct(CMatchFinder *p);
 | |
| ++
 | |
| ++/* Conditions:
 | |
| ++     historySize <= 3 GB
 | |
| ++     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
 | |
| ++*/
 | |
| ++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
 | |
| ++    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
 | |
| ++    ISzAlloc *alloc);
 | |
| ++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
 | |
| ++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
 | |
| ++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
 | |
| ++
 | |
| ++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
 | |
| ++    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
 | |
| ++    UInt32 *distances, UInt32 maxLen);
 | |
| ++
 | |
| ++/*
 | |
| ++Conditions:
 | |
| ++  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
 | |
| ++  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
 | |
| ++*/
 | |
| ++
 | |
| ++typedef void (*Mf_Init_Func)(void *object);
 | |
| ++typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
 | |
| ++typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
 | |
| ++typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
 | |
| ++typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
 | |
| ++typedef void (*Mf_Skip_Func)(void *object, UInt32);
 | |
| ++
 | |
| ++typedef struct _IMatchFinder
 | |
| ++{
 | |
| ++  Mf_Init_Func Init;
 | |
| ++  Mf_GetIndexByte_Func GetIndexByte;
 | |
| ++  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
 | |
| ++  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
 | |
| ++  Mf_GetMatches_Func GetMatches;
 | |
| ++  Mf_Skip_Func Skip;
 | |
| ++} IMatchFinder;
 | |
| ++
 | |
| ++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
 | |
| ++
 | |
| ++void MatchFinder_Init(CMatchFinder *p);
 | |
| ++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
 | |
| ++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
 | |
| ++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
 | |
| ++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
 | |
| ++
 | |
| ++#ifdef __cplusplus
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| ++#endif
 | |
| +--- /dev/null
 | |
| ++++ b/include/linux/lzma/LzHash.h
 | |
| +@@ -0,0 +1,54 @@
 | |
| ++/* LzHash.h -- HASH functions for LZ algorithms
 | |
| ++2009-02-07 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#ifndef __LZ_HASH_H
 | |
| ++#define __LZ_HASH_H
 | |
| ++
 | |
| ++#define kHash2Size (1 << 10)
 | |
| ++#define kHash3Size (1 << 16)
 | |
| ++#define kHash4Size (1 << 20)
 | |
| ++
 | |
| ++#define kFix3HashSize (kHash2Size)
 | |
| ++#define kFix4HashSize (kHash2Size + kHash3Size)
 | |
| ++#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
 | |
| ++
 | |
| ++#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
 | |
| ++
 | |
| ++#define HASH3_CALC { \
 | |
| ++  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
 | |
| ++  hash2Value = temp & (kHash2Size - 1); \
 | |
| ++  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
 | |
| ++
 | |
| ++#define HASH4_CALC { \
 | |
| ++  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
 | |
| ++  hash2Value = temp & (kHash2Size - 1); \
 | |
| ++  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
 | |
| ++  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
 | |
| ++
 | |
| ++#define HASH5_CALC { \
 | |
| ++  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
 | |
| ++  hash2Value = temp & (kHash2Size - 1); \
 | |
| ++  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
 | |
| ++  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
 | |
| ++  hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
 | |
| ++  hash4Value &= (kHash4Size - 1); }
 | |
| ++
 | |
| ++/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
 | |
| ++#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
 | |
| ++
 | |
| ++
 | |
| ++#define MT_HASH2_CALC \
 | |
| ++  hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
 | |
| ++
 | |
| ++#define MT_HASH3_CALC { \
 | |
| ++  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
 | |
| ++  hash2Value = temp & (kHash2Size - 1); \
 | |
| ++  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
 | |
| ++
 | |
| ++#define MT_HASH4_CALC { \
 | |
| ++  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
 | |
| ++  hash2Value = temp & (kHash2Size - 1); \
 | |
| ++  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
 | |
| ++  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
 | |
| ++
 | |
| ++#endif
 | |
| +--- /dev/null
 | |
| ++++ b/include/linux/lzma/LzmaDec.h
 | |
| +@@ -0,0 +1,231 @@
 | |
| ++/* LzmaDec.h -- LZMA Decoder
 | |
| ++2009-02-07 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#ifndef __LZMA_DEC_H
 | |
| ++#define __LZMA_DEC_H
 | |
| ++
 | |
| ++#include "Types.h"
 | |
| ++
 | |
| ++#ifdef __cplusplus
 | |
| ++extern "C" {
 | |
| ++#endif
 | |
| ++
 | |
| ++/* #define _LZMA_PROB32 */
 | |
| ++/* _LZMA_PROB32 can increase the speed on some CPUs,
 | |
| ++   but memory usage for CLzmaDec::probs will be doubled in that case */
 | |
| ++
 | |
| ++#ifdef _LZMA_PROB32
 | |
| ++#define CLzmaProb UInt32
 | |
| ++#else
 | |
| ++#define CLzmaProb UInt16
 | |
| ++#endif
 | |
| ++
 | |
| ++
 | |
| ++/* ---------- LZMA Properties ---------- */
 | |
| ++
 | |
| ++#define LZMA_PROPS_SIZE 5
 | |
| ++
 | |
| ++typedef struct _CLzmaProps
 | |
| ++{
 | |
| ++  unsigned lc, lp, pb;
 | |
| ++  UInt32 dicSize;
 | |
| ++} CLzmaProps;
 | |
| ++
 | |
| ++/* LzmaProps_Decode - decodes properties
 | |
| ++Returns:
 | |
| ++  SZ_OK
 | |
| ++  SZ_ERROR_UNSUPPORTED - Unsupported properties
 | |
| ++*/
 | |
| ++
 | |
| ++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
 | |
| ++
 | |
| ++
 | |
| ++/* ---------- LZMA Decoder state ---------- */
 | |
| ++
 | |
| ++/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
 | |
| ++   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
 | |
| ++
 | |
| ++#define LZMA_REQUIRED_INPUT_MAX 20
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  CLzmaProps prop;
 | |
| ++  CLzmaProb *probs;
 | |
| ++  Byte *dic;
 | |
| ++  const Byte *buf;
 | |
| ++  UInt32 range, code;
 | |
| ++  SizeT dicPos;
 | |
| ++  SizeT dicBufSize;
 | |
| ++  UInt32 processedPos;
 | |
| ++  UInt32 checkDicSize;
 | |
| ++  unsigned state;
 | |
| ++  UInt32 reps[4];
 | |
| ++  unsigned remainLen;
 | |
| ++  int needFlush;
 | |
| ++  int needInitState;
 | |
| ++  UInt32 numProbs;
 | |
| ++  unsigned tempBufSize;
 | |
| ++  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
 | |
| ++} CLzmaDec;
 | |
| ++
 | |
| ++#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
 | |
| ++
 | |
| ++void LzmaDec_Init(CLzmaDec *p);
 | |
| ++
 | |
| ++/* There are two types of LZMA streams:
 | |
| ++     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
 | |
| ++     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
 | |
| ++
 | |
| ++typedef enum
 | |
| ++{
 | |
| ++  LZMA_FINISH_ANY,   /* finish at any point */
 | |
| ++  LZMA_FINISH_END    /* block must be finished at the end */
 | |
| ++} ELzmaFinishMode;
 | |
| ++
 | |
| ++/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
 | |
| ++
 | |
| ++   You must use LZMA_FINISH_END, when you know that current output buffer
 | |
| ++   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
 | |
| ++
 | |
| ++   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
 | |
| ++   and output value of destLen will be less than output buffer size limit.
 | |
| ++   You can check status result also.
 | |
| ++
 | |
| ++   You can use multiple checks to test data integrity after full decompression:
 | |
| ++     1) Check Result and "status" variable.
 | |
| ++     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
 | |
| ++     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
 | |
| ++        You must use correct finish mode in that case. */
 | |
| ++
 | |
| ++typedef enum
 | |
| ++{
 | |
| ++  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
 | |
| ++  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
 | |
| ++  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
 | |
| ++  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
 | |
| ++  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
 | |
| ++} ELzmaStatus;
 | |
| ++
 | |
| ++/* ELzmaStatus is used only as output value for function call */
 | |
| ++
 | |
| ++
 | |
| ++/* ---------- Interfaces ---------- */
 | |
| ++
 | |
| ++/* There are 3 levels of interfaces:
 | |
| ++     1) Dictionary Interface
 | |
| ++     2) Buffer Interface
 | |
| ++     3) One Call Interface
 | |
| ++   You can select any of these interfaces, but don't mix functions from different
 | |
| ++   groups for same object. */
 | |
| ++
 | |
| ++
 | |
| ++/* There are two variants to allocate state for Dictionary Interface:
 | |
| ++     1) LzmaDec_Allocate / LzmaDec_Free
 | |
| ++     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
 | |
| ++   You can use variant 2, if you set dictionary buffer manually.
 | |
| ++   For Buffer Interface you must always use variant 1.
 | |
| ++
 | |
| ++LzmaDec_Allocate* can return:
 | |
| ++  SZ_OK
 | |
| ++  SZ_ERROR_MEM         - Memory allocation error
 | |
| ++  SZ_ERROR_UNSUPPORTED - Unsupported properties
 | |
| ++*/
 | |
| ++
 | |
| ++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
 | |
| ++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
 | |
| ++
 | |
| ++SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
 | |
| ++void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
 | |
| ++
 | |
| ++/* ---------- Dictionary Interface ---------- */
 | |
| ++
 | |
| ++/* You can use it, if you want to eliminate the overhead for data copying from
 | |
| ++   dictionary to some other external buffer.
 | |
| ++   You must work with CLzmaDec variables directly in this interface.
 | |
| ++
 | |
| ++   STEPS:
 | |
| ++     LzmaDec_Constr()
 | |
| ++     LzmaDec_Allocate()
 | |
| ++     for (each new stream)
 | |
| ++     {
 | |
| ++       LzmaDec_Init()
 | |
| ++       while (it needs more decompression)
 | |
| ++       {
 | |
| ++         LzmaDec_DecodeToDic()
 | |
| ++         use data from CLzmaDec::dic and update CLzmaDec::dicPos
 | |
| ++       }
 | |
| ++     }
 | |
| ++     LzmaDec_Free()
 | |
| ++*/
 | |
| ++
 | |
| ++/* LzmaDec_DecodeToDic
 | |
| ++
 | |
| ++   The decoding to internal dictionary buffer (CLzmaDec::dic).
 | |
| ++   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
 | |
| ++
 | |
| ++finishMode:
 | |
| ++  It has meaning only if the decoding reaches output limit (dicLimit).
 | |
| ++  LZMA_FINISH_ANY - Decode just dicLimit bytes.
 | |
| ++  LZMA_FINISH_END - Stream must be finished after dicLimit.
 | |
| ++
 | |
| ++Returns:
 | |
| ++  SZ_OK
 | |
| ++    status:
 | |
| ++      LZMA_STATUS_FINISHED_WITH_MARK
 | |
| ++      LZMA_STATUS_NOT_FINISHED
 | |
| ++      LZMA_STATUS_NEEDS_MORE_INPUT
 | |
| ++      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
 | |
| ++  SZ_ERROR_DATA - Data error
 | |
| ++*/
 | |
| ++
 | |
| ++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
 | |
| ++    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
 | |
| ++
 | |
| ++
 | |
| ++/* ---------- Buffer Interface ---------- */
 | |
| ++
 | |
| ++/* It's zlib-like interface.
 | |
| ++   See LzmaDec_DecodeToDic description for information about STEPS and return results,
 | |
| ++   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
 | |
| ++   to work with CLzmaDec variables manually.
 | |
| ++
 | |
| ++finishMode:
 | |
| ++  It has meaning only if the decoding reaches output limit (*destLen).
 | |
| ++  LZMA_FINISH_ANY - Decode just destLen bytes.
 | |
| ++  LZMA_FINISH_END - Stream must be finished after (*destLen).
 | |
| ++*/
 | |
| ++
 | |
| ++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
 | |
| ++    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
 | |
| ++
 | |
| ++
 | |
| ++/* ---------- One Call Interface ---------- */
 | |
| ++
 | |
| ++/* LzmaDecode
 | |
| ++
 | |
| ++finishMode:
 | |
| ++  It has meaning only if the decoding reaches output limit (*destLen).
 | |
| ++  LZMA_FINISH_ANY - Decode just destLen bytes.
 | |
| ++  LZMA_FINISH_END - Stream must be finished after (*destLen).
 | |
| ++
 | |
| ++Returns:
 | |
| ++  SZ_OK
 | |
| ++    status:
 | |
| ++      LZMA_STATUS_FINISHED_WITH_MARK
 | |
| ++      LZMA_STATUS_NOT_FINISHED
 | |
| ++      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
 | |
| ++  SZ_ERROR_DATA - Data error
 | |
| ++  SZ_ERROR_MEM  - Memory allocation error
 | |
| ++  SZ_ERROR_UNSUPPORTED - Unsupported properties
 | |
| ++  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
 | |
| ++*/
 | |
| ++
 | |
| ++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
 | |
| ++    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
 | |
| ++    ELzmaStatus *status, ISzAlloc *alloc);
 | |
| ++
 | |
| ++#ifdef __cplusplus
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| ++#endif
 | |
| +--- /dev/null
 | |
| ++++ b/include/linux/lzma/LzmaEnc.h
 | |
| +@@ -0,0 +1,80 @@
 | |
| ++/*  LzmaEnc.h -- LZMA Encoder
 | |
| ++2009-02-07 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#ifndef __LZMA_ENC_H
 | |
| ++#define __LZMA_ENC_H
 | |
| ++
 | |
| ++#include "Types.h"
 | |
| ++
 | |
| ++#ifdef __cplusplus
 | |
| ++extern "C" {
 | |
| ++#endif
 | |
| ++
 | |
| ++#define LZMA_PROPS_SIZE 5
 | |
| ++
 | |
| ++typedef struct _CLzmaEncProps
 | |
| ++{
 | |
| ++  int level;       /*  0 <= level <= 9 */
 | |
| ++  UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
 | |
| ++                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
 | |
| ++                       default = (1 << 24) */
 | |
| ++  int lc;          /* 0 <= lc <= 8, default = 3 */
 | |
| ++  int lp;          /* 0 <= lp <= 4, default = 0 */
 | |
| ++  int pb;          /* 0 <= pb <= 4, default = 2 */
 | |
| ++  int algo;        /* 0 - fast, 1 - normal, default = 1 */
 | |
| ++  int fb;          /* 5 <= fb <= 273, default = 32 */
 | |
| ++  int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
 | |
| ++  int numHashBytes; /* 2, 3 or 4, default = 4 */
 | |
| ++  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */
 | |
| ++  unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
 | |
| ++  int numThreads;  /* 1 or 2, default = 2 */
 | |
| ++} CLzmaEncProps;
 | |
| ++
 | |
| ++void LzmaEncProps_Init(CLzmaEncProps *p);
 | |
| ++void LzmaEncProps_Normalize(CLzmaEncProps *p);
 | |
| ++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
 | |
| ++
 | |
| ++
 | |
| ++/* ---------- CLzmaEncHandle Interface ---------- */
 | |
| ++
 | |
| ++/* LzmaEnc_* functions can return the following exit codes:
 | |
| ++Returns:
 | |
| ++  SZ_OK           - OK
 | |
| ++  SZ_ERROR_MEM    - Memory allocation error
 | |
| ++  SZ_ERROR_PARAM  - Incorrect paramater in props
 | |
| ++  SZ_ERROR_WRITE  - Write callback error.
 | |
| ++  SZ_ERROR_PROGRESS - some break from progress callback
 | |
| ++  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
 | |
| ++*/
 | |
| ++
 | |
| ++typedef void * CLzmaEncHandle;
 | |
| ++
 | |
| ++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
 | |
| ++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| ++SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
 | |
| ++SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
 | |
| ++SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
 | |
| ++    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| ++SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
 | |
| ++    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| ++
 | |
| ++/* ---------- One Call Interface ---------- */
 | |
| ++
 | |
| ++/* LzmaEncode
 | |
| ++Return code:
 | |
| ++  SZ_OK               - OK
 | |
| ++  SZ_ERROR_MEM        - Memory allocation error
 | |
| ++  SZ_ERROR_PARAM      - Incorrect paramater
 | |
| ++  SZ_ERROR_OUTPUT_EOF - output buffer overflow
 | |
| ++  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
 | |
| ++*/
 | |
| ++
 | |
| ++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
 | |
| ++    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
 | |
| ++    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
 | |
| ++
 | |
| ++#ifdef __cplusplus
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| ++#endif
 | |
| +--- /dev/null
 | |
| ++++ b/include/linux/lzma/Types.h
 | |
| +@@ -0,0 +1,226 @@
 | |
| ++/* Types.h -- Basic types
 | |
| ++2009-11-23 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#ifndef __7Z_TYPES_H
 | |
| ++#define __7Z_TYPES_H
 | |
| ++
 | |
| ++#include <stddef.h>
 | |
| ++
 | |
| ++#ifdef _WIN32
 | |
| ++#include <windows.h>
 | |
| ++#endif
 | |
| ++
 | |
| ++#ifndef EXTERN_C_BEGIN
 | |
| ++#ifdef __cplusplus
 | |
| ++#define EXTERN_C_BEGIN extern "C" {
 | |
| ++#define EXTERN_C_END }
 | |
| ++#else
 | |
| ++#define EXTERN_C_BEGIN
 | |
| ++#define EXTERN_C_END
 | |
| ++#endif
 | |
| ++#endif
 | |
| ++
 | |
| ++EXTERN_C_BEGIN
 | |
| ++
 | |
| ++#define SZ_OK 0
 | |
| ++
 | |
| ++#define SZ_ERROR_DATA 1
 | |
| ++#define SZ_ERROR_MEM 2
 | |
| ++#define SZ_ERROR_CRC 3
 | |
| ++#define SZ_ERROR_UNSUPPORTED 4
 | |
| ++#define SZ_ERROR_PARAM 5
 | |
| ++#define SZ_ERROR_INPUT_EOF 6
 | |
| ++#define SZ_ERROR_OUTPUT_EOF 7
 | |
| ++#define SZ_ERROR_READ 8
 | |
| ++#define SZ_ERROR_WRITE 9
 | |
| ++#define SZ_ERROR_PROGRESS 10
 | |
| ++#define SZ_ERROR_FAIL 11
 | |
| ++#define SZ_ERROR_THREAD 12
 | |
| ++
 | |
| ++#define SZ_ERROR_ARCHIVE 16
 | |
| ++#define SZ_ERROR_NO_ARCHIVE 17
 | |
| ++
 | |
| ++typedef int SRes;
 | |
| ++
 | |
| ++#ifdef _WIN32
 | |
| ++typedef DWORD WRes;
 | |
| ++#else
 | |
| ++typedef int WRes;
 | |
| ++#endif
 | |
| ++
 | |
| ++#ifndef RINOK
 | |
| ++#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
 | |
| ++#endif
 | |
| ++
 | |
| ++typedef unsigned char Byte;
 | |
| ++typedef short Int16;
 | |
| ++typedef unsigned short UInt16;
 | |
| ++
 | |
| ++#ifdef _LZMA_UINT32_IS_ULONG
 | |
| ++typedef long Int32;
 | |
| ++typedef unsigned long UInt32;
 | |
| ++#else
 | |
| ++typedef int Int32;
 | |
| ++typedef unsigned int UInt32;
 | |
| ++#endif
 | |
| ++
 | |
| ++#ifdef _SZ_NO_INT_64
 | |
| ++
 | |
| ++/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
 | |
| ++   NOTES: Some code will work incorrectly in that case! */
 | |
| ++
 | |
| ++typedef long Int64;
 | |
| ++typedef unsigned long UInt64;
 | |
| ++
 | |
| ++#else
 | |
| ++
 | |
| ++#if defined(_MSC_VER) || defined(__BORLANDC__)
 | |
| ++typedef __int64 Int64;
 | |
| ++typedef unsigned __int64 UInt64;
 | |
| ++#else
 | |
| ++typedef long long int Int64;
 | |
| ++typedef unsigned long long int UInt64;
 | |
| ++#endif
 | |
| ++
 | |
| ++#endif
 | |
| ++
 | |
| ++#ifdef _LZMA_NO_SYSTEM_SIZE_T
 | |
| ++typedef UInt32 SizeT;
 | |
| ++#else
 | |
| ++typedef size_t SizeT;
 | |
| ++#endif
 | |
| ++
 | |
| ++typedef int Bool;
 | |
| ++#define True 1
 | |
| ++#define False 0
 | |
| ++
 | |
| ++
 | |
| ++#ifdef _WIN32
 | |
| ++#define MY_STD_CALL __stdcall
 | |
| ++#else
 | |
| ++#define MY_STD_CALL
 | |
| ++#endif
 | |
| ++
 | |
| ++#ifdef _MSC_VER
 | |
| ++
 | |
| ++#if _MSC_VER >= 1300
 | |
| ++#define MY_NO_INLINE __declspec(noinline)
 | |
| ++#else
 | |
| ++#define MY_NO_INLINE
 | |
| ++#endif
 | |
| ++
 | |
| ++#define MY_CDECL __cdecl
 | |
| ++#define MY_FAST_CALL __fastcall
 | |
| ++
 | |
| ++#else
 | |
| ++
 | |
| ++#define MY_CDECL
 | |
| ++#define MY_FAST_CALL
 | |
| ++
 | |
| ++#endif
 | |
| ++
 | |
| ++
 | |
| ++/* The following interfaces use first parameter as pointer to structure */
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  SRes (*Read)(void *p, void *buf, size_t *size);
 | |
| ++    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
 | |
| ++       (output(*size) < input(*size)) is allowed */
 | |
| ++} ISeqInStream;
 | |
| ++
 | |
| ++/* it can return SZ_ERROR_INPUT_EOF */
 | |
| ++SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
 | |
| ++SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
 | |
| ++SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  size_t (*Write)(void *p, const void *buf, size_t size);
 | |
| ++    /* Returns: result - the number of actually written bytes.
 | |
| ++       (result < size) means error */
 | |
| ++} ISeqOutStream;
 | |
| ++
 | |
| ++typedef enum
 | |
| ++{
 | |
| ++  SZ_SEEK_SET = 0,
 | |
| ++  SZ_SEEK_CUR = 1,
 | |
| ++  SZ_SEEK_END = 2
 | |
| ++} ESzSeek;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
 | |
| ++  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
 | |
| ++} ISeekInStream;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  SRes (*Look)(void *p, void **buf, size_t *size);
 | |
| ++    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
 | |
| ++       (output(*size) > input(*size)) is not allowed
 | |
| ++       (output(*size) < input(*size)) is allowed */
 | |
| ++  SRes (*Skip)(void *p, size_t offset);
 | |
| ++    /* offset must be <= output(*size) of Look */
 | |
| ++
 | |
| ++  SRes (*Read)(void *p, void *buf, size_t *size);
 | |
| ++    /* reads directly (without buffer). It's same as ISeqInStream::Read */
 | |
| ++  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
 | |
| ++} ILookInStream;
 | |
| ++
 | |
| ++SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
 | |
| ++SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
 | |
| ++
 | |
| ++/* reads via ILookInStream::Read */
 | |
| ++SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
 | |
| ++SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
 | |
| ++
 | |
| ++#define LookToRead_BUF_SIZE (1 << 14)
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  ILookInStream s;
 | |
| ++  ISeekInStream *realStream;
 | |
| ++  size_t pos;
 | |
| ++  size_t size;
 | |
| ++  Byte buf[LookToRead_BUF_SIZE];
 | |
| ++} CLookToRead;
 | |
| ++
 | |
| ++void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
 | |
| ++void LookToRead_Init(CLookToRead *p);
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  ISeqInStream s;
 | |
| ++  ILookInStream *realStream;
 | |
| ++} CSecToLook;
 | |
| ++
 | |
| ++void SecToLook_CreateVTable(CSecToLook *p);
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  ISeqInStream s;
 | |
| ++  ILookInStream *realStream;
 | |
| ++} CSecToRead;
 | |
| ++
 | |
| ++void SecToRead_CreateVTable(CSecToRead *p);
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
 | |
| ++    /* Returns: result. (result != SZ_OK) means break.
 | |
| ++       Value (UInt64)(Int64)-1 for size means unknown value. */
 | |
| ++} ICompressProgress;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  void *(*Alloc)(void *p, size_t size);
 | |
| ++  void (*Free)(void *p, void *address); /* address can be 0 */
 | |
| ++} ISzAlloc;
 | |
| ++
 | |
| ++#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
 | |
| ++#define IAlloc_Free(p, a) (p)->Free((p), a)
 | |
| ++
 | |
| ++EXTERN_C_END
 | |
| ++
 | |
| ++#endif
 | |
| +--- a/include/uapi/linux/jffs2.h
 | |
| ++++ b/include/uapi/linux/jffs2.h
 | |
| +@@ -46,6 +46,7 @@
 | |
| + #define JFFS2_COMPR_DYNRUBIN	0x05
 | |
| + #define JFFS2_COMPR_ZLIB	0x06
 | |
| + #define JFFS2_COMPR_LZO		0x07
 | |
| ++#define JFFS2_COMPR_LZMA	0x08
 | |
| + /* Compatibility flags. */
 | |
| + #define JFFS2_COMPAT_MASK 0xc000      /* What do to if an unknown nodetype is found */
 | |
| + #define JFFS2_NODE_ACCURATE 0x2000
 | |
| +--- a/lib/Kconfig
 | |
| ++++ b/lib/Kconfig
 | |
| +@@ -316,6 +316,12 @@ config ZSTD_DECOMPRESS
 | |
| + 
 | |
| + source "lib/xz/Kconfig"
 | |
| + 
 | |
| ++config LZMA_COMPRESS
 | |
| ++    tristate
 | |
| ++
 | |
| ++config LZMA_DECOMPRESS
 | |
| ++    tristate
 | |
| ++
 | |
| + #
 | |
| + # These all provide a common interface (hence the apparent duplication with
 | |
| + # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
 | |
| +--- a/lib/Makefile
 | |
| ++++ b/lib/Makefile
 | |
| +@@ -136,6 +136,16 @@ CFLAGS_kobject.o += -DDEBUG
 | |
| + CFLAGS_kobject_uevent.o += -DDEBUG
 | |
| + endif
 | |
| + 
 | |
| ++ifdef CONFIG_JFFS2_ZLIB
 | |
| ++  CONFIG_ZLIB_INFLATE:=y
 | |
| ++  CONFIG_ZLIB_DEFLATE:=y
 | |
| ++endif
 | |
| ++
 | |
| ++ifdef CONFIG_JFFS2_LZMA
 | |
| ++  CONFIG_LZMA_DECOMPRESS:=y
 | |
| ++  CONFIG_LZMA_COMPRESS:=y
 | |
| ++endif
 | |
| ++
 | |
| + obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o
 | |
| + CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any)
 | |
| + 
 | |
| +@@ -191,6 +201,8 @@ obj-$(CONFIG_ZSTD_COMPRESS) += zstd/
 | |
| + obj-$(CONFIG_ZSTD_DECOMPRESS) += zstd/
 | |
| + obj-$(CONFIG_XZ_DEC) += xz/
 | |
| + obj-$(CONFIG_RAID6_PQ) += raid6/
 | |
| ++obj-$(CONFIG_LZMA_COMPRESS) += lzma/
 | |
| ++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/
 | |
| + 
 | |
| + lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
 | |
| + lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
 | |
| +--- /dev/null
 | |
| ++++ b/lib/lzma/LzFind.c
 | |
| +@@ -0,0 +1,761 @@
 | |
| ++/* LzFind.c -- Match finder for LZ algorithms
 | |
| ++2009-04-22 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#include <string.h>
 | |
| ++
 | |
| ++#include "LzFind.h"
 | |
| ++#include "LzHash.h"
 | |
| ++
 | |
| ++#define kEmptyHashValue 0
 | |
| ++#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
 | |
| ++#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
 | |
| ++#define kNormalizeMask (~(kNormalizeStepMin - 1))
 | |
| ++#define kMaxHistorySize ((UInt32)3 << 30)
 | |
| ++
 | |
| ++#define kStartMaxLen 3
 | |
| ++
 | |
| ++static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  if (!p->directInput)
 | |
| ++  {
 | |
| ++    alloc->Free(alloc, p->bufferBase);
 | |
| ++    p->bufferBase = 0;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
 | |
| ++
 | |
| ++static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
 | |
| ++  if (p->directInput)
 | |
| ++  {
 | |
| ++    p->blockSize = blockSize;
 | |
| ++    return 1;
 | |
| ++  }
 | |
| ++  if (p->bufferBase == 0 || p->blockSize != blockSize)
 | |
| ++  {
 | |
| ++    LzInWindow_Free(p, alloc);
 | |
| ++    p->blockSize = blockSize;
 | |
| ++    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
 | |
| ++  }
 | |
| ++  return (p->bufferBase != 0);
 | |
| ++}
 | |
| ++
 | |
| ++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
 | |
| ++Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
 | |
| ++
 | |
| ++UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
 | |
| ++
 | |
| ++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
 | |
| ++{
 | |
| ++  p->posLimit -= subValue;
 | |
| ++  p->pos -= subValue;
 | |
| ++  p->streamPos -= subValue;
 | |
| ++}
 | |
| ++
 | |
| ++static void MatchFinder_ReadBlock(CMatchFinder *p)
 | |
| ++{
 | |
| ++  if (p->streamEndWasReached || p->result != SZ_OK)
 | |
| ++    return;
 | |
| ++  if (p->directInput)
 | |
| ++  {
 | |
| ++    UInt32 curSize = 0xFFFFFFFF - p->streamPos;
 | |
| ++    if (curSize > p->directInputRem)
 | |
| ++      curSize = (UInt32)p->directInputRem;
 | |
| ++    p->directInputRem -= curSize;
 | |
| ++    p->streamPos += curSize;
 | |
| ++    if (p->directInputRem == 0)
 | |
| ++      p->streamEndWasReached = 1;
 | |
| ++    return;
 | |
| ++  }
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    Byte *dest = p->buffer + (p->streamPos - p->pos);
 | |
| ++    size_t size = (p->bufferBase + p->blockSize - dest);
 | |
| ++    if (size == 0)
 | |
| ++      return;
 | |
| ++    p->result = p->stream->Read(p->stream, dest, &size);
 | |
| ++    if (p->result != SZ_OK)
 | |
| ++      return;
 | |
| ++    if (size == 0)
 | |
| ++    {
 | |
| ++      p->streamEndWasReached = 1;
 | |
| ++      return;
 | |
| ++    }
 | |
| ++    p->streamPos += (UInt32)size;
 | |
| ++    if (p->streamPos - p->pos > p->keepSizeAfter)
 | |
| ++      return;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++void MatchFinder_MoveBlock(CMatchFinder *p)
 | |
| ++{
 | |
| ++  memmove(p->bufferBase,
 | |
| ++    p->buffer - p->keepSizeBefore,
 | |
| ++    (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
 | |
| ++  p->buffer = p->bufferBase + p->keepSizeBefore;
 | |
| ++}
 | |
| ++
 | |
| ++int MatchFinder_NeedMove(CMatchFinder *p)
 | |
| ++{
 | |
| ++  if (p->directInput)
 | |
| ++    return 0;
 | |
| ++  /* if (p->streamEndWasReached) return 0; */
 | |
| ++  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
 | |
| ++}
 | |
| ++
 | |
| ++void MatchFinder_ReadIfRequired(CMatchFinder *p)
 | |
| ++{
 | |
| ++  if (p->streamEndWasReached)
 | |
| ++    return;
 | |
| ++  if (p->keepSizeAfter >= p->streamPos - p->pos)
 | |
| ++    MatchFinder_ReadBlock(p);
 | |
| ++}
 | |
| ++
 | |
| ++static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
 | |
| ++{
 | |
| ++  if (MatchFinder_NeedMove(p))
 | |
| ++    MatchFinder_MoveBlock(p);
 | |
| ++  MatchFinder_ReadBlock(p);
 | |
| ++}
 | |
| ++
 | |
| ++static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
 | |
| ++{
 | |
| ++  p->cutValue = 32;
 | |
| ++  p->btMode = 1;
 | |
| ++  p->numHashBytes = 4;
 | |
| ++  p->bigHash = 0;
 | |
| ++}
 | |
| ++
 | |
| ++#define kCrcPoly 0xEDB88320
 | |
| ++
 | |
| ++void MatchFinder_Construct(CMatchFinder *p)
 | |
| ++{
 | |
| ++  UInt32 i;
 | |
| ++  p->bufferBase = 0;
 | |
| ++  p->directInput = 0;
 | |
| ++  p->hash = 0;
 | |
| ++  MatchFinder_SetDefaultSettings(p);
 | |
| ++
 | |
| ++  for (i = 0; i < 256; i++)
 | |
| ++  {
 | |
| ++    UInt32 r = i;
 | |
| ++    int j;
 | |
| ++    for (j = 0; j < 8; j++)
 | |
| ++      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
 | |
| ++    p->crc[i] = r;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  alloc->Free(alloc, p->hash);
 | |
| ++  p->hash = 0;
 | |
| ++}
 | |
| ++
 | |
| ++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  MatchFinder_FreeThisClassMemory(p, alloc);
 | |
| ++  LzInWindow_Free(p, alloc);
 | |
| ++}
 | |
| ++
 | |
| ++static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
 | |
| ++  if (sizeInBytes / sizeof(CLzRef) != num)
 | |
| ++    return 0;
 | |
| ++  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
 | |
| ++}
 | |
| ++
 | |
| ++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
 | |
| ++    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
 | |
| ++    ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  UInt32 sizeReserv;
 | |
| ++  if (historySize > kMaxHistorySize)
 | |
| ++  {
 | |
| ++    MatchFinder_Free(p, alloc);
 | |
| ++    return 0;
 | |
| ++  }
 | |
| ++  sizeReserv = historySize >> 1;
 | |
| ++  if (historySize > ((UInt32)2 << 30))
 | |
| ++    sizeReserv = historySize >> 2;
 | |
| ++  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
 | |
| ++
 | |
| ++  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
 | |
| ++  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
 | |
| ++  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
 | |
| ++  if (LzInWindow_Create(p, sizeReserv, alloc))
 | |
| ++  {
 | |
| ++    UInt32 newCyclicBufferSize = historySize + 1;
 | |
| ++    UInt32 hs;
 | |
| ++    p->matchMaxLen = matchMaxLen;
 | |
| ++    {
 | |
| ++      p->fixedHashSize = 0;
 | |
| ++      if (p->numHashBytes == 2)
 | |
| ++        hs = (1 << 16) - 1;
 | |
| ++      else
 | |
| ++      {
 | |
| ++        hs = historySize - 1;
 | |
| ++        hs |= (hs >> 1);
 | |
| ++        hs |= (hs >> 2);
 | |
| ++        hs |= (hs >> 4);
 | |
| ++        hs |= (hs >> 8);
 | |
| ++        hs >>= 1;
 | |
| ++        hs |= 0xFFFF; /* don't change it! It's required for Deflate */
 | |
| ++        if (hs > (1 << 24))
 | |
| ++        {
 | |
| ++          if (p->numHashBytes == 3)
 | |
| ++            hs = (1 << 24) - 1;
 | |
| ++          else
 | |
| ++            hs >>= 1;
 | |
| ++        }
 | |
| ++      }
 | |
| ++      p->hashMask = hs;
 | |
| ++      hs++;
 | |
| ++      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
 | |
| ++      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
 | |
| ++      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
 | |
| ++      hs += p->fixedHashSize;
 | |
| ++    }
 | |
| ++
 | |
| ++    {
 | |
| ++      UInt32 prevSize = p->hashSizeSum + p->numSons;
 | |
| ++      UInt32 newSize;
 | |
| ++      p->historySize = historySize;
 | |
| ++      p->hashSizeSum = hs;
 | |
| ++      p->cyclicBufferSize = newCyclicBufferSize;
 | |
| ++      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
 | |
| ++      newSize = p->hashSizeSum + p->numSons;
 | |
| ++      if (p->hash != 0 && prevSize == newSize)
 | |
| ++        return 1;
 | |
| ++      MatchFinder_FreeThisClassMemory(p, alloc);
 | |
| ++      p->hash = AllocRefs(newSize, alloc);
 | |
| ++      if (p->hash != 0)
 | |
| ++      {
 | |
| ++        p->son = p->hash + p->hashSizeSum;
 | |
| ++        return 1;
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++  MatchFinder_Free(p, alloc);
 | |
| ++  return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void MatchFinder_SetLimits(CMatchFinder *p)
 | |
| ++{
 | |
| ++  UInt32 limit = kMaxValForNormalize - p->pos;
 | |
| ++  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
 | |
| ++  if (limit2 < limit)
 | |
| ++    limit = limit2;
 | |
| ++  limit2 = p->streamPos - p->pos;
 | |
| ++  if (limit2 <= p->keepSizeAfter)
 | |
| ++  {
 | |
| ++    if (limit2 > 0)
 | |
| ++      limit2 = 1;
 | |
| ++  }
 | |
| ++  else
 | |
| ++    limit2 -= p->keepSizeAfter;
 | |
| ++  if (limit2 < limit)
 | |
| ++    limit = limit2;
 | |
| ++  {
 | |
| ++    UInt32 lenLimit = p->streamPos - p->pos;
 | |
| ++    if (lenLimit > p->matchMaxLen)
 | |
| ++      lenLimit = p->matchMaxLen;
 | |
| ++    p->lenLimit = lenLimit;
 | |
| ++  }
 | |
| ++  p->posLimit = p->pos + limit;
 | |
| ++}
 | |
| ++
 | |
| ++void MatchFinder_Init(CMatchFinder *p)
 | |
| ++{
 | |
| ++  UInt32 i;
 | |
| ++  for (i = 0; i < p->hashSizeSum; i++)
 | |
| ++    p->hash[i] = kEmptyHashValue;
 | |
| ++  p->cyclicBufferPos = 0;
 | |
| ++  p->buffer = p->bufferBase;
 | |
| ++  p->pos = p->streamPos = p->cyclicBufferSize;
 | |
| ++  p->result = SZ_OK;
 | |
| ++  p->streamEndWasReached = 0;
 | |
| ++  MatchFinder_ReadBlock(p);
 | |
| ++  MatchFinder_SetLimits(p);
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
 | |
| ++{
 | |
| ++  return (p->pos - p->historySize - 1) & kNormalizeMask;
 | |
| ++}
 | |
| ++
 | |
| ++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
 | |
| ++{
 | |
| ++  UInt32 i;
 | |
| ++  for (i = 0; i < numItems; i++)
 | |
| ++  {
 | |
| ++    UInt32 value = items[i];
 | |
| ++    if (value <= subValue)
 | |
| ++      value = kEmptyHashValue;
 | |
| ++    else
 | |
| ++      value -= subValue;
 | |
| ++    items[i] = value;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static void MatchFinder_Normalize(CMatchFinder *p)
 | |
| ++{
 | |
| ++  UInt32 subValue = MatchFinder_GetSubValue(p);
 | |
| ++  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
 | |
| ++  MatchFinder_ReduceOffsets(p, subValue);
 | |
| ++}
 | |
| ++
 | |
| ++static void MatchFinder_CheckLimits(CMatchFinder *p)
 | |
| ++{
 | |
| ++  if (p->pos == kMaxValForNormalize)
 | |
| ++    MatchFinder_Normalize(p);
 | |
| ++  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
 | |
| ++    MatchFinder_CheckAndMoveAndRead(p);
 | |
| ++  if (p->cyclicBufferPos == p->cyclicBufferSize)
 | |
| ++    p->cyclicBufferPos = 0;
 | |
| ++  MatchFinder_SetLimits(p);
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
 | |
| ++    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
 | |
| ++    UInt32 *distances, UInt32 maxLen)
 | |
| ++{
 | |
| ++  son[_cyclicBufferPos] = curMatch;
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    UInt32 delta = pos - curMatch;
 | |
| ++    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
 | |
| ++      return distances;
 | |
| ++    {
 | |
| ++      const Byte *pb = cur - delta;
 | |
| ++      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
 | |
| ++      if (pb[maxLen] == cur[maxLen] && *pb == *cur)
 | |
| ++      {
 | |
| ++        UInt32 len = 0;
 | |
| ++        while (++len != lenLimit)
 | |
| ++          if (pb[len] != cur[len])
 | |
| ++            break;
 | |
| ++        if (maxLen < len)
 | |
| ++        {
 | |
| ++          *distances++ = maxLen = len;
 | |
| ++          *distances++ = delta - 1;
 | |
| ++          if (len == lenLimit)
 | |
| ++            return distances;
 | |
| ++        }
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
 | |
| ++    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
 | |
| ++    UInt32 *distances, UInt32 maxLen)
 | |
| ++{
 | |
| ++  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
 | |
| ++  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
 | |
| ++  UInt32 len0 = 0, len1 = 0;
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    UInt32 delta = pos - curMatch;
 | |
| ++    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
 | |
| ++    {
 | |
| ++      *ptr0 = *ptr1 = kEmptyHashValue;
 | |
| ++      return distances;
 | |
| ++    }
 | |
| ++    {
 | |
| ++      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
 | |
| ++      const Byte *pb = cur - delta;
 | |
| ++      UInt32 len = (len0 < len1 ? len0 : len1);
 | |
| ++      if (pb[len] == cur[len])
 | |
| ++      {
 | |
| ++        if (++len != lenLimit && pb[len] == cur[len])
 | |
| ++          while (++len != lenLimit)
 | |
| ++            if (pb[len] != cur[len])
 | |
| ++              break;
 | |
| ++        if (maxLen < len)
 | |
| ++        {
 | |
| ++          *distances++ = maxLen = len;
 | |
| ++          *distances++ = delta - 1;
 | |
| ++          if (len == lenLimit)
 | |
| ++          {
 | |
| ++            *ptr1 = pair[0];
 | |
| ++            *ptr0 = pair[1];
 | |
| ++            return distances;
 | |
| ++          }
 | |
| ++        }
 | |
| ++      }
 | |
| ++      if (pb[len] < cur[len])
 | |
| ++      {
 | |
| ++        *ptr1 = curMatch;
 | |
| ++        ptr1 = pair + 1;
 | |
| ++        curMatch = *ptr1;
 | |
| ++        len1 = len;
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        *ptr0 = curMatch;
 | |
| ++        ptr0 = pair;
 | |
| ++        curMatch = *ptr0;
 | |
| ++        len0 = len;
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
 | |
| ++    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
 | |
| ++{
 | |
| ++  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
 | |
| ++  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
 | |
| ++  UInt32 len0 = 0, len1 = 0;
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    UInt32 delta = pos - curMatch;
 | |
| ++    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
 | |
| ++    {
 | |
| ++      *ptr0 = *ptr1 = kEmptyHashValue;
 | |
| ++      return;
 | |
| ++    }
 | |
| ++    {
 | |
| ++      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
 | |
| ++      const Byte *pb = cur - delta;
 | |
| ++      UInt32 len = (len0 < len1 ? len0 : len1);
 | |
| ++      if (pb[len] == cur[len])
 | |
| ++      {
 | |
| ++        while (++len != lenLimit)
 | |
| ++          if (pb[len] != cur[len])
 | |
| ++            break;
 | |
| ++        {
 | |
| ++          if (len == lenLimit)
 | |
| ++          {
 | |
| ++            *ptr1 = pair[0];
 | |
| ++            *ptr0 = pair[1];
 | |
| ++            return;
 | |
| ++          }
 | |
| ++        }
 | |
| ++      }
 | |
| ++      if (pb[len] < cur[len])
 | |
| ++      {
 | |
| ++        *ptr1 = curMatch;
 | |
| ++        ptr1 = pair + 1;
 | |
| ++        curMatch = *ptr1;
 | |
| ++        len1 = len;
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        *ptr0 = curMatch;
 | |
| ++        ptr0 = pair;
 | |
| ++        curMatch = *ptr0;
 | |
| ++        len0 = len;
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++#define MOVE_POS \
 | |
| ++  ++p->cyclicBufferPos; \
 | |
| ++  p->buffer++; \
 | |
| ++  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
 | |
| ++
 | |
| ++#define MOVE_POS_RET MOVE_POS return offset;
 | |
| ++
 | |
| ++static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
 | |
| ++
 | |
| ++#define GET_MATCHES_HEADER2(minLen, ret_op) \
 | |
| ++  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
 | |
| ++  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
 | |
| ++  cur = p->buffer;
 | |
| ++
 | |
| ++#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
 | |
| ++#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue)
 | |
| ++
 | |
| ++#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
 | |
| ++
 | |
| ++#define GET_MATCHES_FOOTER(offset, maxLen) \
 | |
| ++  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
 | |
| ++  distances + offset, maxLen) - distances); MOVE_POS_RET;
 | |
| ++
 | |
| ++#define SKIP_FOOTER \
 | |
| ++  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
 | |
| ++
 | |
| ++static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| ++{
 | |
| ++  UInt32 offset;
 | |
| ++  GET_MATCHES_HEADER(2)
 | |
| ++  HASH2_CALC;
 | |
| ++  curMatch = p->hash[hashValue];
 | |
| ++  p->hash[hashValue] = p->pos;
 | |
| ++  offset = 0;
 | |
| ++  GET_MATCHES_FOOTER(offset, 1)
 | |
| ++}
 | |
| ++
 | |
| ++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| ++{
 | |
| ++  UInt32 offset;
 | |
| ++  GET_MATCHES_HEADER(3)
 | |
| ++  HASH_ZIP_CALC;
 | |
| ++  curMatch = p->hash[hashValue];
 | |
| ++  p->hash[hashValue] = p->pos;
 | |
| ++  offset = 0;
 | |
| ++  GET_MATCHES_FOOTER(offset, 2)
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| ++{
 | |
| ++  UInt32 hash2Value, delta2, maxLen, offset;
 | |
| ++  GET_MATCHES_HEADER(3)
 | |
| ++
 | |
| ++  HASH3_CALC;
 | |
| ++
 | |
| ++  delta2 = p->pos - p->hash[hash2Value];
 | |
| ++  curMatch = p->hash[kFix3HashSize + hashValue];
 | |
| ++
 | |
| ++  p->hash[hash2Value] =
 | |
| ++  p->hash[kFix3HashSize + hashValue] = p->pos;
 | |
| ++
 | |
| ++
 | |
| ++  maxLen = 2;
 | |
| ++  offset = 0;
 | |
| ++  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
 | |
| ++  {
 | |
| ++    for (; maxLen != lenLimit; maxLen++)
 | |
| ++      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
 | |
| ++        break;
 | |
| ++    distances[0] = maxLen;
 | |
| ++    distances[1] = delta2 - 1;
 | |
| ++    offset = 2;
 | |
| ++    if (maxLen == lenLimit)
 | |
| ++    {
 | |
| ++      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
 | |
| ++      MOVE_POS_RET;
 | |
| ++    }
 | |
| ++  }
 | |
| ++  GET_MATCHES_FOOTER(offset, maxLen)
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| ++{
 | |
| ++  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
 | |
| ++  GET_MATCHES_HEADER(4)
 | |
| ++
 | |
| ++  HASH4_CALC;
 | |
| ++
 | |
| ++  delta2 = p->pos - p->hash[                hash2Value];
 | |
| ++  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
 | |
| ++  curMatch = p->hash[kFix4HashSize + hashValue];
 | |
| ++
 | |
| ++  p->hash[                hash2Value] =
 | |
| ++  p->hash[kFix3HashSize + hash3Value] =
 | |
| ++  p->hash[kFix4HashSize + hashValue] = p->pos;
 | |
| ++
 | |
| ++  maxLen = 1;
 | |
| ++  offset = 0;
 | |
| ++  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
 | |
| ++  {
 | |
| ++    distances[0] = maxLen = 2;
 | |
| ++    distances[1] = delta2 - 1;
 | |
| ++    offset = 2;
 | |
| ++  }
 | |
| ++  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
 | |
| ++  {
 | |
| ++    maxLen = 3;
 | |
| ++    distances[offset + 1] = delta3 - 1;
 | |
| ++    offset += 2;
 | |
| ++    delta2 = delta3;
 | |
| ++  }
 | |
| ++  if (offset != 0)
 | |
| ++  {
 | |
| ++    for (; maxLen != lenLimit; maxLen++)
 | |
| ++      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
 | |
| ++        break;
 | |
| ++    distances[offset - 2] = maxLen;
 | |
| ++    if (maxLen == lenLimit)
 | |
| ++    {
 | |
| ++      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
 | |
| ++      MOVE_POS_RET;
 | |
| ++    }
 | |
| ++  }
 | |
| ++  if (maxLen < 3)
 | |
| ++    maxLen = 3;
 | |
| ++  GET_MATCHES_FOOTER(offset, maxLen)
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| ++{
 | |
| ++  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
 | |
| ++  GET_MATCHES_HEADER(4)
 | |
| ++
 | |
| ++  HASH4_CALC;
 | |
| ++
 | |
| ++  delta2 = p->pos - p->hash[                hash2Value];
 | |
| ++  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
 | |
| ++  curMatch = p->hash[kFix4HashSize + hashValue];
 | |
| ++
 | |
| ++  p->hash[                hash2Value] =
 | |
| ++  p->hash[kFix3HashSize + hash3Value] =
 | |
| ++  p->hash[kFix4HashSize + hashValue] = p->pos;
 | |
| ++
 | |
| ++  maxLen = 1;
 | |
| ++  offset = 0;
 | |
| ++  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
 | |
| ++  {
 | |
| ++    distances[0] = maxLen = 2;
 | |
| ++    distances[1] = delta2 - 1;
 | |
| ++    offset = 2;
 | |
| ++  }
 | |
| ++  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
 | |
| ++  {
 | |
| ++    maxLen = 3;
 | |
| ++    distances[offset + 1] = delta3 - 1;
 | |
| ++    offset += 2;
 | |
| ++    delta2 = delta3;
 | |
| ++  }
 | |
| ++  if (offset != 0)
 | |
| ++  {
 | |
| ++    for (; maxLen != lenLimit; maxLen++)
 | |
| ++      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
 | |
| ++        break;
 | |
| ++    distances[offset - 2] = maxLen;
 | |
| ++    if (maxLen == lenLimit)
 | |
| ++    {
 | |
| ++      p->son[p->cyclicBufferPos] = curMatch;
 | |
| ++      MOVE_POS_RET;
 | |
| ++    }
 | |
| ++  }
 | |
| ++  if (maxLen < 3)
 | |
| ++    maxLen = 3;
 | |
| ++  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
 | |
| ++    distances + offset, maxLen) - (distances));
 | |
| ++  MOVE_POS_RET
 | |
| ++}
 | |
| ++
 | |
| ++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
 | |
| ++{
 | |
| ++  UInt32 offset;
 | |
| ++  GET_MATCHES_HEADER(3)
 | |
| ++  HASH_ZIP_CALC;
 | |
| ++  curMatch = p->hash[hashValue];
 | |
| ++  p->hash[hashValue] = p->pos;
 | |
| ++  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
 | |
| ++    distances, 2) - (distances));
 | |
| ++  MOVE_POS_RET
 | |
| ++}
 | |
| ++
 | |
| ++static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    SKIP_HEADER(2)
 | |
| ++    HASH2_CALC;
 | |
| ++    curMatch = p->hash[hashValue];
 | |
| ++    p->hash[hashValue] = p->pos;
 | |
| ++    SKIP_FOOTER
 | |
| ++  }
 | |
| ++  while (--num != 0);
 | |
| ++}
 | |
| ++
 | |
| ++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    SKIP_HEADER(3)
 | |
| ++    HASH_ZIP_CALC;
 | |
| ++    curMatch = p->hash[hashValue];
 | |
| ++    p->hash[hashValue] = p->pos;
 | |
| ++    SKIP_FOOTER
 | |
| ++  }
 | |
| ++  while (--num != 0);
 | |
| ++}
 | |
| ++
 | |
| ++static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    UInt32 hash2Value;
 | |
| ++    SKIP_HEADER(3)
 | |
| ++    HASH3_CALC;
 | |
| ++    curMatch = p->hash[kFix3HashSize + hashValue];
 | |
| ++    p->hash[hash2Value] =
 | |
| ++    p->hash[kFix3HashSize + hashValue] = p->pos;
 | |
| ++    SKIP_FOOTER
 | |
| ++  }
 | |
| ++  while (--num != 0);
 | |
| ++}
 | |
| ++
 | |
| ++static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    UInt32 hash2Value, hash3Value;
 | |
| ++    SKIP_HEADER(4)
 | |
| ++    HASH4_CALC;
 | |
| ++    curMatch = p->hash[kFix4HashSize + hashValue];
 | |
| ++    p->hash[                hash2Value] =
 | |
| ++    p->hash[kFix3HashSize + hash3Value] = p->pos;
 | |
| ++    p->hash[kFix4HashSize + hashValue] = p->pos;
 | |
| ++    SKIP_FOOTER
 | |
| ++  }
 | |
| ++  while (--num != 0);
 | |
| ++}
 | |
| ++
 | |
| ++static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    UInt32 hash2Value, hash3Value;
 | |
| ++    SKIP_HEADER(4)
 | |
| ++    HASH4_CALC;
 | |
| ++    curMatch = p->hash[kFix4HashSize + hashValue];
 | |
| ++    p->hash[                hash2Value] =
 | |
| ++    p->hash[kFix3HashSize + hash3Value] =
 | |
| ++    p->hash[kFix4HashSize + hashValue] = p->pos;
 | |
| ++    p->son[p->cyclicBufferPos] = curMatch;
 | |
| ++    MOVE_POS
 | |
| ++  }
 | |
| ++  while (--num != 0);
 | |
| ++}
 | |
| ++
 | |
| ++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    SKIP_HEADER(3)
 | |
| ++    HASH_ZIP_CALC;
 | |
| ++    curMatch = p->hash[hashValue];
 | |
| ++    p->hash[hashValue] = p->pos;
 | |
| ++    p->son[p->cyclicBufferPos] = curMatch;
 | |
| ++    MOVE_POS
 | |
| ++  }
 | |
| ++  while (--num != 0);
 | |
| ++}
 | |
| ++
 | |
| ++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
 | |
| ++{
 | |
| ++  vTable->Init = (Mf_Init_Func)MatchFinder_Init;
 | |
| ++  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
 | |
| ++  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
 | |
| ++  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
 | |
| ++  if (!p->btMode)
 | |
| ++  {
 | |
| ++    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
 | |
| ++    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
 | |
| ++  }
 | |
| ++  else if (p->numHashBytes == 2)
 | |
| ++  {
 | |
| ++    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
 | |
| ++    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
 | |
| ++  }
 | |
| ++  else if (p->numHashBytes == 3)
 | |
| ++  {
 | |
| ++    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
 | |
| ++    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
 | |
| ++  }
 | |
| ++  else
 | |
| ++  {
 | |
| ++    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
 | |
| ++    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
 | |
| ++  }
 | |
| ++}
 | |
| +--- /dev/null
 | |
| ++++ b/lib/lzma/LzmaDec.c
 | |
| +@@ -0,0 +1,999 @@
 | |
| ++/* LzmaDec.c -- LZMA Decoder
 | |
| ++2009-09-20 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#include "LzmaDec.h"
 | |
| ++
 | |
| ++#include <string.h>
 | |
| ++
 | |
| ++#define kNumTopBits 24
 | |
| ++#define kTopValue ((UInt32)1 << kNumTopBits)
 | |
| ++
 | |
| ++#define kNumBitModelTotalBits 11
 | |
| ++#define kBitModelTotal (1 << kNumBitModelTotalBits)
 | |
| ++#define kNumMoveBits 5
 | |
| ++
 | |
| ++#define RC_INIT_SIZE 5
 | |
| ++
 | |
| ++#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
 | |
| ++
 | |
| ++#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
 | |
| ++#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
 | |
| ++#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
 | |
| ++#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
 | |
| ++  { UPDATE_0(p); i = (i + i); A0; } else \
 | |
| ++  { UPDATE_1(p); i = (i + i) + 1; A1; }
 | |
| ++#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
 | |
| ++
 | |
| ++#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
 | |
| ++#define TREE_DECODE(probs, limit, i) \
 | |
| ++  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
 | |
| ++
 | |
| ++/* #define _LZMA_SIZE_OPT */
 | |
| ++
 | |
| ++#ifdef _LZMA_SIZE_OPT
 | |
| ++#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
 | |
| ++#else
 | |
| ++#define TREE_6_DECODE(probs, i) \
 | |
| ++  { i = 1; \
 | |
| ++  TREE_GET_BIT(probs, i); \
 | |
| ++  TREE_GET_BIT(probs, i); \
 | |
| ++  TREE_GET_BIT(probs, i); \
 | |
| ++  TREE_GET_BIT(probs, i); \
 | |
| ++  TREE_GET_BIT(probs, i); \
 | |
| ++  TREE_GET_BIT(probs, i); \
 | |
| ++  i -= 0x40; }
 | |
| ++#endif
 | |
| ++
 | |
| ++#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
 | |
| ++
 | |
| ++#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
 | |
| ++#define UPDATE_0_CHECK range = bound;
 | |
| ++#define UPDATE_1_CHECK range -= bound; code -= bound;
 | |
| ++#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
 | |
| ++  { UPDATE_0_CHECK; i = (i + i); A0; } else \
 | |
| ++  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
 | |
| ++#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
 | |
| ++#define TREE_DECODE_CHECK(probs, limit, i) \
 | |
| ++  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
 | |
| ++
 | |
| ++
 | |
| ++#define kNumPosBitsMax 4
 | |
| ++#define kNumPosStatesMax (1 << kNumPosBitsMax)
 | |
| ++
 | |
| ++#define kLenNumLowBits 3
 | |
| ++#define kLenNumLowSymbols (1 << kLenNumLowBits)
 | |
| ++#define kLenNumMidBits 3
 | |
| ++#define kLenNumMidSymbols (1 << kLenNumMidBits)
 | |
| ++#define kLenNumHighBits 8
 | |
| ++#define kLenNumHighSymbols (1 << kLenNumHighBits)
 | |
| ++
 | |
| ++#define LenChoice 0
 | |
| ++#define LenChoice2 (LenChoice + 1)
 | |
| ++#define LenLow (LenChoice2 + 1)
 | |
| ++#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
 | |
| ++#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
 | |
| ++#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
 | |
| ++
 | |
| ++
 | |
| ++#define kNumStates 12
 | |
| ++#define kNumLitStates 7
 | |
| ++
 | |
| ++#define kStartPosModelIndex 4
 | |
| ++#define kEndPosModelIndex 14
 | |
| ++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
 | |
| ++
 | |
| ++#define kNumPosSlotBits 6
 | |
| ++#define kNumLenToPosStates 4
 | |
| ++
 | |
| ++#define kNumAlignBits 4
 | |
| ++#define kAlignTableSize (1 << kNumAlignBits)
 | |
| ++
 | |
| ++#define kMatchMinLen 2
 | |
| ++#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
 | |
| ++
 | |
| ++#define IsMatch 0
 | |
| ++#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
 | |
| ++#define IsRepG0 (IsRep + kNumStates)
 | |
| ++#define IsRepG1 (IsRepG0 + kNumStates)
 | |
| ++#define IsRepG2 (IsRepG1 + kNumStates)
 | |
| ++#define IsRep0Long (IsRepG2 + kNumStates)
 | |
| ++#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
 | |
| ++#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
 | |
| ++#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
 | |
| ++#define LenCoder (Align + kAlignTableSize)
 | |
| ++#define RepLenCoder (LenCoder + kNumLenProbs)
 | |
| ++#define Literal (RepLenCoder + kNumLenProbs)
 | |
| ++
 | |
| ++#define LZMA_BASE_SIZE 1846
 | |
| ++#define LZMA_LIT_SIZE 768
 | |
| ++
 | |
| ++#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
 | |
| ++
 | |
| ++#if Literal != LZMA_BASE_SIZE
 | |
| ++StopCompilingDueBUG
 | |
| ++#endif
 | |
| ++
 | |
| ++#define LZMA_DIC_MIN (1 << 12)
 | |
| ++
 | |
| ++/* First LZMA-symbol is always decoded.
 | |
| ++And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
 | |
| ++Out:
 | |
| ++  Result:
 | |
| ++    SZ_OK - OK
 | |
| ++    SZ_ERROR_DATA - Error
 | |
| ++  p->remainLen:
 | |
| ++    < kMatchSpecLenStart : normal remain
 | |
| ++    = kMatchSpecLenStart : finished
 | |
| ++    = kMatchSpecLenStart + 1 : Flush marker
 | |
| ++    = kMatchSpecLenStart + 2 : State Init Marker
 | |
| ++*/
 | |
| ++
 | |
| ++static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
 | |
| ++{
 | |
| ++  CLzmaProb *probs = p->probs;
 | |
| ++
 | |
| ++  unsigned state = p->state;
 | |
| ++  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
 | |
| ++  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
 | |
| ++  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
 | |
| ++  unsigned lc = p->prop.lc;
 | |
| ++
 | |
| ++  Byte *dic = p->dic;
 | |
| ++  SizeT dicBufSize = p->dicBufSize;
 | |
| ++  SizeT dicPos = p->dicPos;
 | |
| ++
 | |
| ++  UInt32 processedPos = p->processedPos;
 | |
| ++  UInt32 checkDicSize = p->checkDicSize;
 | |
| ++  unsigned len = 0;
 | |
| ++
 | |
| ++  const Byte *buf = p->buf;
 | |
| ++  UInt32 range = p->range;
 | |
| ++  UInt32 code = p->code;
 | |
| ++
 | |
| ++  do
 | |
| ++  {
 | |
| ++    CLzmaProb *prob;
 | |
| ++    UInt32 bound;
 | |
| ++    unsigned ttt;
 | |
| ++    unsigned posState = processedPos & pbMask;
 | |
| ++
 | |
| ++    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
 | |
| ++    IF_BIT_0(prob)
 | |
| ++    {
 | |
| ++      unsigned symbol;
 | |
| ++      UPDATE_0(prob);
 | |
| ++      prob = probs + Literal;
 | |
| ++      if (checkDicSize != 0 || processedPos != 0)
 | |
| ++        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
 | |
| ++        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
 | |
| ++
 | |
| ++      if (state < kNumLitStates)
 | |
| ++      {
 | |
| ++        state -= (state < 4) ? state : 3;
 | |
| ++        symbol = 1;
 | |
| ++        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
 | |
| ++        unsigned offs = 0x100;
 | |
| ++        state -= (state < 10) ? 3 : 6;
 | |
| ++        symbol = 1;
 | |
| ++        do
 | |
| ++        {
 | |
| ++          unsigned bit;
 | |
| ++          CLzmaProb *probLit;
 | |
| ++          matchByte <<= 1;
 | |
| ++          bit = (matchByte & offs);
 | |
| ++          probLit = prob + offs + bit + symbol;
 | |
| ++          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
 | |
| ++        }
 | |
| ++        while (symbol < 0x100);
 | |
| ++      }
 | |
| ++      dic[dicPos++] = (Byte)symbol;
 | |
| ++      processedPos++;
 | |
| ++      continue;
 | |
| ++    }
 | |
| ++    else
 | |
| ++    {
 | |
| ++      UPDATE_1(prob);
 | |
| ++      prob = probs + IsRep + state;
 | |
| ++      IF_BIT_0(prob)
 | |
| ++      {
 | |
| ++        UPDATE_0(prob);
 | |
| ++        state += kNumStates;
 | |
| ++        prob = probs + LenCoder;
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        UPDATE_1(prob);
 | |
| ++        if (checkDicSize == 0 && processedPos == 0)
 | |
| ++          return SZ_ERROR_DATA;
 | |
| ++        prob = probs + IsRepG0 + state;
 | |
| ++        IF_BIT_0(prob)
 | |
| ++        {
 | |
| ++          UPDATE_0(prob);
 | |
| ++          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
 | |
| ++          IF_BIT_0(prob)
 | |
| ++          {
 | |
| ++            UPDATE_0(prob);
 | |
| ++            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
 | |
| ++            dicPos++;
 | |
| ++            processedPos++;
 | |
| ++            state = state < kNumLitStates ? 9 : 11;
 | |
| ++            continue;
 | |
| ++          }
 | |
| ++          UPDATE_1(prob);
 | |
| ++        }
 | |
| ++        else
 | |
| ++        {
 | |
| ++          UInt32 distance;
 | |
| ++          UPDATE_1(prob);
 | |
| ++          prob = probs + IsRepG1 + state;
 | |
| ++          IF_BIT_0(prob)
 | |
| ++          {
 | |
| ++            UPDATE_0(prob);
 | |
| ++            distance = rep1;
 | |
| ++          }
 | |
| ++          else
 | |
| ++          {
 | |
| ++            UPDATE_1(prob);
 | |
| ++            prob = probs + IsRepG2 + state;
 | |
| ++            IF_BIT_0(prob)
 | |
| ++            {
 | |
| ++              UPDATE_0(prob);
 | |
| ++              distance = rep2;
 | |
| ++            }
 | |
| ++            else
 | |
| ++            {
 | |
| ++              UPDATE_1(prob);
 | |
| ++              distance = rep3;
 | |
| ++              rep3 = rep2;
 | |
| ++            }
 | |
| ++            rep2 = rep1;
 | |
| ++          }
 | |
| ++          rep1 = rep0;
 | |
| ++          rep0 = distance;
 | |
| ++        }
 | |
| ++        state = state < kNumLitStates ? 8 : 11;
 | |
| ++        prob = probs + RepLenCoder;
 | |
| ++      }
 | |
| ++      {
 | |
| ++        unsigned limit, offset;
 | |
| ++        CLzmaProb *probLen = prob + LenChoice;
 | |
| ++        IF_BIT_0(probLen)
 | |
| ++        {
 | |
| ++          UPDATE_0(probLen);
 | |
| ++          probLen = prob + LenLow + (posState << kLenNumLowBits);
 | |
| ++          offset = 0;
 | |
| ++          limit = (1 << kLenNumLowBits);
 | |
| ++        }
 | |
| ++        else
 | |
| ++        {
 | |
| ++          UPDATE_1(probLen);
 | |
| ++          probLen = prob + LenChoice2;
 | |
| ++          IF_BIT_0(probLen)
 | |
| ++          {
 | |
| ++            UPDATE_0(probLen);
 | |
| ++            probLen = prob + LenMid + (posState << kLenNumMidBits);
 | |
| ++            offset = kLenNumLowSymbols;
 | |
| ++            limit = (1 << kLenNumMidBits);
 | |
| ++          }
 | |
| ++          else
 | |
| ++          {
 | |
| ++            UPDATE_1(probLen);
 | |
| ++            probLen = prob + LenHigh;
 | |
| ++            offset = kLenNumLowSymbols + kLenNumMidSymbols;
 | |
| ++            limit = (1 << kLenNumHighBits);
 | |
| ++          }
 | |
| ++        }
 | |
| ++        TREE_DECODE(probLen, limit, len);
 | |
| ++        len += offset;
 | |
| ++      }
 | |
| ++
 | |
| ++      if (state >= kNumStates)
 | |
| ++      {
 | |
| ++        UInt32 distance;
 | |
| ++        prob = probs + PosSlot +
 | |
| ++            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
 | |
| ++        TREE_6_DECODE(prob, distance);
 | |
| ++        if (distance >= kStartPosModelIndex)
 | |
| ++        {
 | |
| ++          unsigned posSlot = (unsigned)distance;
 | |
| ++          int numDirectBits = (int)(((distance >> 1) - 1));
 | |
| ++          distance = (2 | (distance & 1));
 | |
| ++          if (posSlot < kEndPosModelIndex)
 | |
| ++          {
 | |
| ++            distance <<= numDirectBits;
 | |
| ++            prob = probs + SpecPos + distance - posSlot - 1;
 | |
| ++            {
 | |
| ++              UInt32 mask = 1;
 | |
| ++              unsigned i = 1;
 | |
| ++              do
 | |
| ++              {
 | |
| ++                GET_BIT2(prob + i, i, ; , distance |= mask);
 | |
| ++                mask <<= 1;
 | |
| ++              }
 | |
| ++              while (--numDirectBits != 0);
 | |
| ++            }
 | |
| ++          }
 | |
| ++          else
 | |
| ++          {
 | |
| ++            numDirectBits -= kNumAlignBits;
 | |
| ++            do
 | |
| ++            {
 | |
| ++              NORMALIZE
 | |
| ++              range >>= 1;
 | |
| ++
 | |
| ++              {
 | |
| ++                UInt32 t;
 | |
| ++                code -= range;
 | |
| ++                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
 | |
| ++                distance = (distance << 1) + (t + 1);
 | |
| ++                code += range & t;
 | |
| ++              }
 | |
| ++              /*
 | |
| ++              distance <<= 1;
 | |
| ++              if (code >= range)
 | |
| ++              {
 | |
| ++                code -= range;
 | |
| ++                distance |= 1;
 | |
| ++              }
 | |
| ++              */
 | |
| ++            }
 | |
| ++            while (--numDirectBits != 0);
 | |
| ++            prob = probs + Align;
 | |
| ++            distance <<= kNumAlignBits;
 | |
| ++            {
 | |
| ++              unsigned i = 1;
 | |
| ++              GET_BIT2(prob + i, i, ; , distance |= 1);
 | |
| ++              GET_BIT2(prob + i, i, ; , distance |= 2);
 | |
| ++              GET_BIT2(prob + i, i, ; , distance |= 4);
 | |
| ++              GET_BIT2(prob + i, i, ; , distance |= 8);
 | |
| ++            }
 | |
| ++            if (distance == (UInt32)0xFFFFFFFF)
 | |
| ++            {
 | |
| ++              len += kMatchSpecLenStart;
 | |
| ++              state -= kNumStates;
 | |
| ++              break;
 | |
| ++            }
 | |
| ++          }
 | |
| ++        }
 | |
| ++        rep3 = rep2;
 | |
| ++        rep2 = rep1;
 | |
| ++        rep1 = rep0;
 | |
| ++        rep0 = distance + 1;
 | |
| ++        if (checkDicSize == 0)
 | |
| ++        {
 | |
| ++          if (distance >= processedPos)
 | |
| ++            return SZ_ERROR_DATA;
 | |
| ++        }
 | |
| ++        else if (distance >= checkDicSize)
 | |
| ++          return SZ_ERROR_DATA;
 | |
| ++        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
 | |
| ++      }
 | |
| ++
 | |
| ++      len += kMatchMinLen;
 | |
| ++
 | |
| ++      if (limit == dicPos)
 | |
| ++        return SZ_ERROR_DATA;
 | |
| ++      {
 | |
| ++        SizeT rem = limit - dicPos;
 | |
| ++        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
 | |
| ++        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
 | |
| ++
 | |
| ++        processedPos += curLen;
 | |
| ++
 | |
| ++        len -= curLen;
 | |
| ++        if (pos + curLen <= dicBufSize)
 | |
| ++        {
 | |
| ++          Byte *dest = dic + dicPos;
 | |
| ++          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
 | |
| ++          const Byte *lim = dest + curLen;
 | |
| ++          dicPos += curLen;
 | |
| ++          do
 | |
| ++            *(dest) = (Byte)*(dest + src);
 | |
| ++          while (++dest != lim);
 | |
| ++        }
 | |
| ++        else
 | |
| ++        {
 | |
| ++          do
 | |
| ++          {
 | |
| ++            dic[dicPos++] = dic[pos];
 | |
| ++            if (++pos == dicBufSize)
 | |
| ++              pos = 0;
 | |
| ++          }
 | |
| ++          while (--curLen != 0);
 | |
| ++        }
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++  while (dicPos < limit && buf < bufLimit);
 | |
| ++  NORMALIZE;
 | |
| ++  p->buf = buf;
 | |
| ++  p->range = range;
 | |
| ++  p->code = code;
 | |
| ++  p->remainLen = len;
 | |
| ++  p->dicPos = dicPos;
 | |
| ++  p->processedPos = processedPos;
 | |
| ++  p->reps[0] = rep0;
 | |
| ++  p->reps[1] = rep1;
 | |
| ++  p->reps[2] = rep2;
 | |
| ++  p->reps[3] = rep3;
 | |
| ++  p->state = state;
 | |
| ++
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
 | |
| ++{
 | |
| ++  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
 | |
| ++  {
 | |
| ++    Byte *dic = p->dic;
 | |
| ++    SizeT dicPos = p->dicPos;
 | |
| ++    SizeT dicBufSize = p->dicBufSize;
 | |
| ++    unsigned len = p->remainLen;
 | |
| ++    UInt32 rep0 = p->reps[0];
 | |
| ++    if (limit - dicPos < len)
 | |
| ++      len = (unsigned)(limit - dicPos);
 | |
| ++
 | |
| ++    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
 | |
| ++      p->checkDicSize = p->prop.dicSize;
 | |
| ++
 | |
| ++    p->processedPos += len;
 | |
| ++    p->remainLen -= len;
 | |
| ++    while (len-- != 0)
 | |
| ++    {
 | |
| ++      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
 | |
| ++      dicPos++;
 | |
| ++    }
 | |
| ++    p->dicPos = dicPos;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    SizeT limit2 = limit;
 | |
| ++    if (p->checkDicSize == 0)
 | |
| ++    {
 | |
| ++      UInt32 rem = p->prop.dicSize - p->processedPos;
 | |
| ++      if (limit - p->dicPos > rem)
 | |
| ++        limit2 = p->dicPos + rem;
 | |
| ++    }
 | |
| ++    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
 | |
| ++    if (p->processedPos >= p->prop.dicSize)
 | |
| ++      p->checkDicSize = p->prop.dicSize;
 | |
| ++    LzmaDec_WriteRem(p, limit);
 | |
| ++  }
 | |
| ++  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
 | |
| ++
 | |
| ++  if (p->remainLen > kMatchSpecLenStart)
 | |
| ++  {
 | |
| ++    p->remainLen = kMatchSpecLenStart;
 | |
| ++  }
 | |
| ++  return 0;
 | |
| ++}
 | |
| ++
 | |
| ++typedef enum
 | |
| ++{
 | |
| ++  DUMMY_ERROR, /* unexpected end of input stream */
 | |
| ++  DUMMY_LIT,
 | |
| ++  DUMMY_MATCH,
 | |
| ++  DUMMY_REP
 | |
| ++} ELzmaDummy;
 | |
| ++
 | |
| ++static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
 | |
| ++{
 | |
| ++  UInt32 range = p->range;
 | |
| ++  UInt32 code = p->code;
 | |
| ++  const Byte *bufLimit = buf + inSize;
 | |
| ++  CLzmaProb *probs = p->probs;
 | |
| ++  unsigned state = p->state;
 | |
| ++  ELzmaDummy res;
 | |
| ++
 | |
| ++  {
 | |
| ++    CLzmaProb *prob;
 | |
| ++    UInt32 bound;
 | |
| ++    unsigned ttt;
 | |
| ++    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
 | |
| ++
 | |
| ++    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
 | |
| ++    IF_BIT_0_CHECK(prob)
 | |
| ++    {
 | |
| ++      UPDATE_0_CHECK
 | |
| ++
 | |
| ++      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
 | |
| ++
 | |
| ++      prob = probs + Literal;
 | |
| ++      if (p->checkDicSize != 0 || p->processedPos != 0)
 | |
| ++        prob += (LZMA_LIT_SIZE *
 | |
| ++          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
 | |
| ++          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
 | |
| ++
 | |
| ++      if (state < kNumLitStates)
 | |
| ++      {
 | |
| ++        unsigned symbol = 1;
 | |
| ++        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
 | |
| ++            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
 | |
| ++        unsigned offs = 0x100;
 | |
| ++        unsigned symbol = 1;
 | |
| ++        do
 | |
| ++        {
 | |
| ++          unsigned bit;
 | |
| ++          CLzmaProb *probLit;
 | |
| ++          matchByte <<= 1;
 | |
| ++          bit = (matchByte & offs);
 | |
| ++          probLit = prob + offs + bit + symbol;
 | |
| ++          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
 | |
| ++        }
 | |
| ++        while (symbol < 0x100);
 | |
| ++      }
 | |
| ++      res = DUMMY_LIT;
 | |
| ++    }
 | |
| ++    else
 | |
| ++    {
 | |
| ++      unsigned len;
 | |
| ++      UPDATE_1_CHECK;
 | |
| ++
 | |
| ++      prob = probs + IsRep + state;
 | |
| ++      IF_BIT_0_CHECK(prob)
 | |
| ++      {
 | |
| ++        UPDATE_0_CHECK;
 | |
| ++        state = 0;
 | |
| ++        prob = probs + LenCoder;
 | |
| ++        res = DUMMY_MATCH;
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        UPDATE_1_CHECK;
 | |
| ++        res = DUMMY_REP;
 | |
| ++        prob = probs + IsRepG0 + state;
 | |
| ++        IF_BIT_0_CHECK(prob)
 | |
| ++        {
 | |
| ++          UPDATE_0_CHECK;
 | |
| ++          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
 | |
| ++          IF_BIT_0_CHECK(prob)
 | |
| ++          {
 | |
| ++            UPDATE_0_CHECK;
 | |
| ++            NORMALIZE_CHECK;
 | |
| ++            return DUMMY_REP;
 | |
| ++          }
 | |
| ++          else
 | |
| ++          {
 | |
| ++            UPDATE_1_CHECK;
 | |
| ++          }
 | |
| ++        }
 | |
| ++        else
 | |
| ++        {
 | |
| ++          UPDATE_1_CHECK;
 | |
| ++          prob = probs + IsRepG1 + state;
 | |
| ++          IF_BIT_0_CHECK(prob)
 | |
| ++          {
 | |
| ++            UPDATE_0_CHECK;
 | |
| ++          }
 | |
| ++          else
 | |
| ++          {
 | |
| ++            UPDATE_1_CHECK;
 | |
| ++            prob = probs + IsRepG2 + state;
 | |
| ++            IF_BIT_0_CHECK(prob)
 | |
| ++            {
 | |
| ++              UPDATE_0_CHECK;
 | |
| ++            }
 | |
| ++            else
 | |
| ++            {
 | |
| ++              UPDATE_1_CHECK;
 | |
| ++            }
 | |
| ++          }
 | |
| ++        }
 | |
| ++        state = kNumStates;
 | |
| ++        prob = probs + RepLenCoder;
 | |
| ++      }
 | |
| ++      {
 | |
| ++        unsigned limit, offset;
 | |
| ++        CLzmaProb *probLen = prob + LenChoice;
 | |
| ++        IF_BIT_0_CHECK(probLen)
 | |
| ++        {
 | |
| ++          UPDATE_0_CHECK;
 | |
| ++          probLen = prob + LenLow + (posState << kLenNumLowBits);
 | |
| ++          offset = 0;
 | |
| ++          limit = 1 << kLenNumLowBits;
 | |
| ++        }
 | |
| ++        else
 | |
| ++        {
 | |
| ++          UPDATE_1_CHECK;
 | |
| ++          probLen = prob + LenChoice2;
 | |
| ++          IF_BIT_0_CHECK(probLen)
 | |
| ++          {
 | |
| ++            UPDATE_0_CHECK;
 | |
| ++            probLen = prob + LenMid + (posState << kLenNumMidBits);
 | |
| ++            offset = kLenNumLowSymbols;
 | |
| ++            limit = 1 << kLenNumMidBits;
 | |
| ++          }
 | |
| ++          else
 | |
| ++          {
 | |
| ++            UPDATE_1_CHECK;
 | |
| ++            probLen = prob + LenHigh;
 | |
| ++            offset = kLenNumLowSymbols + kLenNumMidSymbols;
 | |
| ++            limit = 1 << kLenNumHighBits;
 | |
| ++          }
 | |
| ++        }
 | |
| ++        TREE_DECODE_CHECK(probLen, limit, len);
 | |
| ++        len += offset;
 | |
| ++      }
 | |
| ++
 | |
| ++      if (state < 4)
 | |
| ++      {
 | |
| ++        unsigned posSlot;
 | |
| ++        prob = probs + PosSlot +
 | |
| ++            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
 | |
| ++            kNumPosSlotBits);
 | |
| ++        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
 | |
| ++        if (posSlot >= kStartPosModelIndex)
 | |
| ++        {
 | |
| ++          int numDirectBits = ((posSlot >> 1) - 1);
 | |
| ++
 | |
| ++          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
 | |
| ++
 | |
| ++          if (posSlot < kEndPosModelIndex)
 | |
| ++          {
 | |
| ++            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
 | |
| ++          }
 | |
| ++          else
 | |
| ++          {
 | |
| ++            numDirectBits -= kNumAlignBits;
 | |
| ++            do
 | |
| ++            {
 | |
| ++              NORMALIZE_CHECK
 | |
| ++              range >>= 1;
 | |
| ++              code -= range & (((code - range) >> 31) - 1);
 | |
| ++              /* if (code >= range) code -= range; */
 | |
| ++            }
 | |
| ++            while (--numDirectBits != 0);
 | |
| ++            prob = probs + Align;
 | |
| ++            numDirectBits = kNumAlignBits;
 | |
| ++          }
 | |
| ++          {
 | |
| ++            unsigned i = 1;
 | |
| ++            do
 | |
| ++            {
 | |
| ++              GET_BIT_CHECK(prob + i, i);
 | |
| ++            }
 | |
| ++            while (--numDirectBits != 0);
 | |
| ++          }
 | |
| ++        }
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++  NORMALIZE_CHECK;
 | |
| ++  return res;
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
 | |
| ++{
 | |
| ++  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
 | |
| ++  p->range = 0xFFFFFFFF;
 | |
| ++  p->needFlush = 0;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
 | |
| ++{
 | |
| ++  p->needFlush = 1;
 | |
| ++  p->remainLen = 0;
 | |
| ++  p->tempBufSize = 0;
 | |
| ++
 | |
| ++  if (initDic)
 | |
| ++  {
 | |
| ++    p->processedPos = 0;
 | |
| ++    p->checkDicSize = 0;
 | |
| ++    p->needInitState = 1;
 | |
| ++  }
 | |
| ++  if (initState)
 | |
| ++    p->needInitState = 1;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaDec_Init(CLzmaDec *p)
 | |
| ++{
 | |
| ++  p->dicPos = 0;
 | |
| ++  LzmaDec_InitDicAndState(p, True, True);
 | |
| ++}
 | |
| ++
 | |
| ++static void LzmaDec_InitStateReal(CLzmaDec *p)
 | |
| ++{
 | |
| ++  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
 | |
| ++  UInt32 i;
 | |
| ++  CLzmaProb *probs = p->probs;
 | |
| ++  for (i = 0; i < numProbs; i++)
 | |
| ++    probs[i] = kBitModelTotal >> 1;
 | |
| ++  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
 | |
| ++  p->state = 0;
 | |
| ++  p->needInitState = 0;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
 | |
| ++    ELzmaFinishMode finishMode, ELzmaStatus *status)
 | |
| ++{
 | |
| ++  SizeT inSize = *srcLen;
 | |
| ++  (*srcLen) = 0;
 | |
| ++  LzmaDec_WriteRem(p, dicLimit);
 | |
| ++
 | |
| ++  *status = LZMA_STATUS_NOT_SPECIFIED;
 | |
| ++
 | |
| ++  while (p->remainLen != kMatchSpecLenStart)
 | |
| ++  {
 | |
| ++      int checkEndMarkNow;
 | |
| ++
 | |
| ++      if (p->needFlush != 0)
 | |
| ++      {
 | |
| ++        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
 | |
| ++          p->tempBuf[p->tempBufSize++] = *src++;
 | |
| ++        if (p->tempBufSize < RC_INIT_SIZE)
 | |
| ++        {
 | |
| ++          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
 | |
| ++          return SZ_OK;
 | |
| ++        }
 | |
| ++        if (p->tempBuf[0] != 0)
 | |
| ++          return SZ_ERROR_DATA;
 | |
| ++
 | |
| ++        LzmaDec_InitRc(p, p->tempBuf);
 | |
| ++        p->tempBufSize = 0;
 | |
| ++      }
 | |
| ++
 | |
| ++      checkEndMarkNow = 0;
 | |
| ++      if (p->dicPos >= dicLimit)
 | |
| ++      {
 | |
| ++        if (p->remainLen == 0 && p->code == 0)
 | |
| ++        {
 | |
| ++          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
 | |
| ++          return SZ_OK;
 | |
| ++        }
 | |
| ++        if (finishMode == LZMA_FINISH_ANY)
 | |
| ++        {
 | |
| ++          *status = LZMA_STATUS_NOT_FINISHED;
 | |
| ++          return SZ_OK;
 | |
| ++        }
 | |
| ++        if (p->remainLen != 0)
 | |
| ++        {
 | |
| ++          *status = LZMA_STATUS_NOT_FINISHED;
 | |
| ++          return SZ_ERROR_DATA;
 | |
| ++        }
 | |
| ++        checkEndMarkNow = 1;
 | |
| ++      }
 | |
| ++
 | |
| ++      if (p->needInitState)
 | |
| ++        LzmaDec_InitStateReal(p);
 | |
| ++
 | |
| ++      if (p->tempBufSize == 0)
 | |
| ++      {
 | |
| ++        SizeT processed;
 | |
| ++        const Byte *bufLimit;
 | |
| ++        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
 | |
| ++        {
 | |
| ++          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
 | |
| ++          if (dummyRes == DUMMY_ERROR)
 | |
| ++          {
 | |
| ++            memcpy(p->tempBuf, src, inSize);
 | |
| ++            p->tempBufSize = (unsigned)inSize;
 | |
| ++            (*srcLen) += inSize;
 | |
| ++            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
 | |
| ++            return SZ_OK;
 | |
| ++          }
 | |
| ++          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
 | |
| ++          {
 | |
| ++            *status = LZMA_STATUS_NOT_FINISHED;
 | |
| ++            return SZ_ERROR_DATA;
 | |
| ++          }
 | |
| ++          bufLimit = src;
 | |
| ++        }
 | |
| ++        else
 | |
| ++          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
 | |
| ++        p->buf = src;
 | |
| ++        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
 | |
| ++          return SZ_ERROR_DATA;
 | |
| ++        processed = (SizeT)(p->buf - src);
 | |
| ++        (*srcLen) += processed;
 | |
| ++        src += processed;
 | |
| ++        inSize -= processed;
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        unsigned rem = p->tempBufSize, lookAhead = 0;
 | |
| ++        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
 | |
| ++          p->tempBuf[rem++] = src[lookAhead++];
 | |
| ++        p->tempBufSize = rem;
 | |
| ++        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
 | |
| ++        {
 | |
| ++          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
 | |
| ++          if (dummyRes == DUMMY_ERROR)
 | |
| ++          {
 | |
| ++            (*srcLen) += lookAhead;
 | |
| ++            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
 | |
| ++            return SZ_OK;
 | |
| ++          }
 | |
| ++          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
 | |
| ++          {
 | |
| ++            *status = LZMA_STATUS_NOT_FINISHED;
 | |
| ++            return SZ_ERROR_DATA;
 | |
| ++          }
 | |
| ++        }
 | |
| ++        p->buf = p->tempBuf;
 | |
| ++        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
 | |
| ++          return SZ_ERROR_DATA;
 | |
| ++        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
 | |
| ++        (*srcLen) += lookAhead;
 | |
| ++        src += lookAhead;
 | |
| ++        inSize -= lookAhead;
 | |
| ++        p->tempBufSize = 0;
 | |
| ++      }
 | |
| ++  }
 | |
| ++  if (p->code == 0)
 | |
| ++    *status = LZMA_STATUS_FINISHED_WITH_MARK;
 | |
| ++  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
 | |
| ++{
 | |
| ++  SizeT outSize = *destLen;
 | |
| ++  SizeT inSize = *srcLen;
 | |
| ++  *srcLen = *destLen = 0;
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    SizeT inSizeCur = inSize, outSizeCur, dicPos;
 | |
| ++    ELzmaFinishMode curFinishMode;
 | |
| ++    SRes res;
 | |
| ++    if (p->dicPos == p->dicBufSize)
 | |
| ++      p->dicPos = 0;
 | |
| ++    dicPos = p->dicPos;
 | |
| ++    if (outSize > p->dicBufSize - dicPos)
 | |
| ++    {
 | |
| ++      outSizeCur = p->dicBufSize;
 | |
| ++      curFinishMode = LZMA_FINISH_ANY;
 | |
| ++    }
 | |
| ++    else
 | |
| ++    {
 | |
| ++      outSizeCur = dicPos + outSize;
 | |
| ++      curFinishMode = finishMode;
 | |
| ++    }
 | |
| ++
 | |
| ++    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
 | |
| ++    src += inSizeCur;
 | |
| ++    inSize -= inSizeCur;
 | |
| ++    *srcLen += inSizeCur;
 | |
| ++    outSizeCur = p->dicPos - dicPos;
 | |
| ++    memcpy(dest, p->dic + dicPos, outSizeCur);
 | |
| ++    dest += outSizeCur;
 | |
| ++    outSize -= outSizeCur;
 | |
| ++    *destLen += outSizeCur;
 | |
| ++    if (res != 0)
 | |
| ++      return res;
 | |
| ++    if (outSizeCur == 0 || outSize == 0)
 | |
| ++      return SZ_OK;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  alloc->Free(alloc, p->probs);
 | |
| ++  p->probs = 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  alloc->Free(alloc, p->dic);
 | |
| ++  p->dic = 0;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  LzmaDec_FreeProbs(p, alloc);
 | |
| ++  LzmaDec_FreeDict(p, alloc);
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
 | |
| ++{
 | |
| ++  UInt32 dicSize;
 | |
| ++  Byte d;
 | |
| ++
 | |
| ++  if (size < LZMA_PROPS_SIZE)
 | |
| ++    return SZ_ERROR_UNSUPPORTED;
 | |
| ++  else
 | |
| ++    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
 | |
| ++
 | |
| ++  if (dicSize < LZMA_DIC_MIN)
 | |
| ++    dicSize = LZMA_DIC_MIN;
 | |
| ++  p->dicSize = dicSize;
 | |
| ++
 | |
| ++  d = data[0];
 | |
| ++  if (d >= (9 * 5 * 5))
 | |
| ++    return SZ_ERROR_UNSUPPORTED;
 | |
| ++
 | |
| ++  p->lc = d % 9;
 | |
| ++  d /= 9;
 | |
| ++  p->pb = d / 5;
 | |
| ++  p->lp = d % 5;
 | |
| ++
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
 | |
| ++  if (p->probs == 0 || numProbs != p->numProbs)
 | |
| ++  {
 | |
| ++    LzmaDec_FreeProbs(p, alloc);
 | |
| ++    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
 | |
| ++    p->numProbs = numProbs;
 | |
| ++    if (p->probs == 0)
 | |
| ++      return SZ_ERROR_MEM;
 | |
| ++  }
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  CLzmaProps propNew;
 | |
| ++  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
 | |
| ++  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
 | |
| ++  p->prop = propNew;
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  CLzmaProps propNew;
 | |
| ++  SizeT dicBufSize;
 | |
| ++  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
 | |
| ++  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
 | |
| ++  dicBufSize = propNew.dicSize;
 | |
| ++  if (p->dic == 0 || dicBufSize != p->dicBufSize)
 | |
| ++  {
 | |
| ++    LzmaDec_FreeDict(p, alloc);
 | |
| ++    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
 | |
| ++    if (p->dic == 0)
 | |
| ++    {
 | |
| ++      LzmaDec_FreeProbs(p, alloc);
 | |
| ++      return SZ_ERROR_MEM;
 | |
| ++    }
 | |
| ++  }
 | |
| ++  p->dicBufSize = dicBufSize;
 | |
| ++  p->prop = propNew;
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
 | |
| ++    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
 | |
| ++    ELzmaStatus *status, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  CLzmaDec p;
 | |
| ++  SRes res;
 | |
| ++  SizeT inSize = *srcLen;
 | |
| ++  SizeT outSize = *destLen;
 | |
| ++  *srcLen = *destLen = 0;
 | |
| ++  if (inSize < RC_INIT_SIZE)
 | |
| ++    return SZ_ERROR_INPUT_EOF;
 | |
| ++
 | |
| ++  LzmaDec_Construct(&p);
 | |
| ++  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
 | |
| ++  if (res != 0)
 | |
| ++    return res;
 | |
| ++  p.dic = dest;
 | |
| ++  p.dicBufSize = outSize;
 | |
| ++
 | |
| ++  LzmaDec_Init(&p);
 | |
| ++
 | |
| ++  *srcLen = inSize;
 | |
| ++  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
 | |
| ++
 | |
| ++  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
 | |
| ++    res = SZ_ERROR_INPUT_EOF;
 | |
| ++
 | |
| ++  (*destLen) = p.dicPos;
 | |
| ++  LzmaDec_FreeProbs(&p, alloc);
 | |
| ++  return res;
 | |
| ++}
 | |
| +--- /dev/null
 | |
| ++++ b/lib/lzma/LzmaEnc.c
 | |
| +@@ -0,0 +1,2271 @@
 | |
| ++/* LzmaEnc.c -- LZMA Encoder
 | |
| ++2009-11-24 : Igor Pavlov : Public domain */
 | |
| ++
 | |
| ++#include <string.h>
 | |
| ++
 | |
| ++/* #define SHOW_STAT */
 | |
| ++/* #define SHOW_STAT2 */
 | |
| ++
 | |
| ++#if defined(SHOW_STAT) || defined(SHOW_STAT2)
 | |
| ++#include <stdio.h>
 | |
| ++#endif
 | |
| ++
 | |
| ++#include "LzmaEnc.h"
 | |
| ++
 | |
| ++/* disable MT */
 | |
| ++#define _7ZIP_ST
 | |
| ++
 | |
| ++#include "LzFind.h"
 | |
| ++#ifndef _7ZIP_ST
 | |
| ++#include "LzFindMt.h"
 | |
| ++#endif
 | |
| ++
 | |
| ++#ifdef SHOW_STAT
 | |
| ++static int ttt = 0;
 | |
| ++#endif
 | |
| ++
 | |
| ++#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
 | |
| ++
 | |
| ++#define kBlockSize (9 << 10)
 | |
| ++#define kUnpackBlockSize (1 << 18)
 | |
| ++#define kMatchArraySize (1 << 21)
 | |
| ++#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
 | |
| ++
 | |
| ++#define kNumMaxDirectBits (31)
 | |
| ++
 | |
| ++#define kNumTopBits 24
 | |
| ++#define kTopValue ((UInt32)1 << kNumTopBits)
 | |
| ++
 | |
| ++#define kNumBitModelTotalBits 11
 | |
| ++#define kBitModelTotal (1 << kNumBitModelTotalBits)
 | |
| ++#define kNumMoveBits 5
 | |
| ++#define kProbInitValue (kBitModelTotal >> 1)
 | |
| ++
 | |
| ++#define kNumMoveReducingBits 4
 | |
| ++#define kNumBitPriceShiftBits 4
 | |
| ++#define kBitPrice (1 << kNumBitPriceShiftBits)
 | |
| ++
 | |
| ++void LzmaEncProps_Init(CLzmaEncProps *p)
 | |
| ++{
 | |
| ++  p->level = 5;
 | |
| ++  p->dictSize = p->mc = 0;
 | |
| ++  p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
 | |
| ++  p->writeEndMark = 0;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEncProps_Normalize(CLzmaEncProps *p)
 | |
| ++{
 | |
| ++  int level = p->level;
 | |
| ++  if (level < 0) level = 5;
 | |
| ++  p->level = level;
 | |
| ++  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
 | |
| ++  if (p->lc < 0) p->lc = 3;
 | |
| ++  if (p->lp < 0) p->lp = 0;
 | |
| ++  if (p->pb < 0) p->pb = 2;
 | |
| ++  if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
 | |
| ++  if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
 | |
| ++  if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
 | |
| ++  if (p->numHashBytes < 0) p->numHashBytes = 4;
 | |
| ++  if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
 | |
| ++  if (p->numThreads < 0)
 | |
| ++    p->numThreads =
 | |
| ++      #ifndef _7ZIP_ST
 | |
| ++      ((p->btMode && p->algo) ? 2 : 1);
 | |
| ++      #else
 | |
| ++      1;
 | |
| ++      #endif
 | |
| ++}
 | |
| ++
 | |
| ++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
 | |
| ++{
 | |
| ++  CLzmaEncProps props = *props2;
 | |
| ++  LzmaEncProps_Normalize(&props);
 | |
| ++  return props.dictSize;
 | |
| ++}
 | |
| ++
 | |
| ++/* #define LZMA_LOG_BSR */
 | |
| ++/* Define it for Intel's CPU */
 | |
| ++
 | |
| ++
 | |
| ++#ifdef LZMA_LOG_BSR
 | |
| ++
 | |
| ++#define kDicLogSizeMaxCompress 30
 | |
| ++
 | |
| ++#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
 | |
| ++
 | |
| ++UInt32 GetPosSlot1(UInt32 pos)
 | |
| ++{
 | |
| ++  UInt32 res;
 | |
| ++  BSR2_RET(pos, res);
 | |
| ++  return res;
 | |
| ++}
 | |
| ++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
 | |
| ++#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
 | |
| ++
 | |
| ++#else
 | |
| ++
 | |
| ++#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
 | |
| ++#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
 | |
| ++
 | |
| ++void LzmaEnc_FastPosInit(Byte *g_FastPos)
 | |
| ++{
 | |
| ++  int c = 2, slotFast;
 | |
| ++  g_FastPos[0] = 0;
 | |
| ++  g_FastPos[1] = 1;
 | |
| ++
 | |
| ++  for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
 | |
| ++  {
 | |
| ++    UInt32 k = (1 << ((slotFast >> 1) - 1));
 | |
| ++    UInt32 j;
 | |
| ++    for (j = 0; j < k; j++, c++)
 | |
| ++      g_FastPos[c] = (Byte)slotFast;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
 | |
| ++  (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
 | |
| ++  res = p->g_FastPos[pos >> i] + (i * 2); }
 | |
| ++/*
 | |
| ++#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
 | |
| ++  p->g_FastPos[pos >> 6] + 12 : \
 | |
| ++  p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
 | |
| ++*/
 | |
| ++
 | |
| ++#define GetPosSlot1(pos) p->g_FastPos[pos]
 | |
| ++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
 | |
| ++#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
 | |
| ++
 | |
| ++#endif
 | |
| ++
 | |
| ++
 | |
| ++#define LZMA_NUM_REPS 4
 | |
| ++
 | |
| ++typedef unsigned CState;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  UInt32 price;
 | |
| ++
 | |
| ++  CState state;
 | |
| ++  int prev1IsChar;
 | |
| ++  int prev2;
 | |
| ++
 | |
| ++  UInt32 posPrev2;
 | |
| ++  UInt32 backPrev2;
 | |
| ++
 | |
| ++  UInt32 posPrev;
 | |
| ++  UInt32 backPrev;
 | |
| ++  UInt32 backs[LZMA_NUM_REPS];
 | |
| ++} COptimal;
 | |
| ++
 | |
| ++#define kNumOpts (1 << 12)
 | |
| ++
 | |
| ++#define kNumLenToPosStates 4
 | |
| ++#define kNumPosSlotBits 6
 | |
| ++#define kDicLogSizeMin 0
 | |
| ++#define kDicLogSizeMax 32
 | |
| ++#define kDistTableSizeMax (kDicLogSizeMax * 2)
 | |
| ++
 | |
| ++
 | |
| ++#define kNumAlignBits 4
 | |
| ++#define kAlignTableSize (1 << kNumAlignBits)
 | |
| ++#define kAlignMask (kAlignTableSize - 1)
 | |
| ++
 | |
| ++#define kStartPosModelIndex 4
 | |
| ++#define kEndPosModelIndex 14
 | |
| ++#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
 | |
| ++
 | |
| ++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
 | |
| ++
 | |
| ++#ifdef _LZMA_PROB32
 | |
| ++#define CLzmaProb UInt32
 | |
| ++#else
 | |
| ++#define CLzmaProb UInt16
 | |
| ++#endif
 | |
| ++
 | |
| ++#define LZMA_PB_MAX 4
 | |
| ++#define LZMA_LC_MAX 8
 | |
| ++#define LZMA_LP_MAX 4
 | |
| ++
 | |
| ++#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
 | |
| ++
 | |
| ++
 | |
| ++#define kLenNumLowBits 3
 | |
| ++#define kLenNumLowSymbols (1 << kLenNumLowBits)
 | |
| ++#define kLenNumMidBits 3
 | |
| ++#define kLenNumMidSymbols (1 << kLenNumMidBits)
 | |
| ++#define kLenNumHighBits 8
 | |
| ++#define kLenNumHighSymbols (1 << kLenNumHighBits)
 | |
| ++
 | |
| ++#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
 | |
| ++
 | |
| ++#define LZMA_MATCH_LEN_MIN 2
 | |
| ++#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
 | |
| ++
 | |
| ++#define kNumStates 12
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  CLzmaProb choice;
 | |
| ++  CLzmaProb choice2;
 | |
| ++  CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
 | |
| ++  CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
 | |
| ++  CLzmaProb high[kLenNumHighSymbols];
 | |
| ++} CLenEnc;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  CLenEnc p;
 | |
| ++  UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
 | |
| ++  UInt32 tableSize;
 | |
| ++  UInt32 counters[LZMA_NUM_PB_STATES_MAX];
 | |
| ++} CLenPriceEnc;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  UInt32 range;
 | |
| ++  Byte cache;
 | |
| ++  UInt64 low;
 | |
| ++  UInt64 cacheSize;
 | |
| ++  Byte *buf;
 | |
| ++  Byte *bufLim;
 | |
| ++  Byte *bufBase;
 | |
| ++  ISeqOutStream *outStream;
 | |
| ++  UInt64 processed;
 | |
| ++  SRes res;
 | |
| ++} CRangeEnc;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  CLzmaProb *litProbs;
 | |
| ++
 | |
| ++  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
 | |
| ++  CLzmaProb isRep[kNumStates];
 | |
| ++  CLzmaProb isRepG0[kNumStates];
 | |
| ++  CLzmaProb isRepG1[kNumStates];
 | |
| ++  CLzmaProb isRepG2[kNumStates];
 | |
| ++  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
 | |
| ++
 | |
| ++  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
 | |
| ++  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
 | |
| ++  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
 | |
| ++
 | |
| ++  CLenPriceEnc lenEnc;
 | |
| ++  CLenPriceEnc repLenEnc;
 | |
| ++
 | |
| ++  UInt32 reps[LZMA_NUM_REPS];
 | |
| ++  UInt32 state;
 | |
| ++} CSaveState;
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  IMatchFinder matchFinder;
 | |
| ++  void *matchFinderObj;
 | |
| ++
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  Bool mtMode;
 | |
| ++  CMatchFinderMt matchFinderMt;
 | |
| ++  #endif
 | |
| ++
 | |
| ++  CMatchFinder matchFinderBase;
 | |
| ++
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  Byte pad[128];
 | |
| ++  #endif
 | |
| ++
 | |
| ++  UInt32 optimumEndIndex;
 | |
| ++  UInt32 optimumCurrentIndex;
 | |
| ++
 | |
| ++  UInt32 longestMatchLength;
 | |
| ++  UInt32 numPairs;
 | |
| ++  UInt32 numAvail;
 | |
| ++  COptimal opt[kNumOpts];
 | |
| ++
 | |
| ++  #ifndef LZMA_LOG_BSR
 | |
| ++  Byte g_FastPos[1 << kNumLogBits];
 | |
| ++  #endif
 | |
| ++
 | |
| ++  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
 | |
| ++  UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
 | |
| ++  UInt32 numFastBytes;
 | |
| ++  UInt32 additionalOffset;
 | |
| ++  UInt32 reps[LZMA_NUM_REPS];
 | |
| ++  UInt32 state;
 | |
| ++
 | |
| ++  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
 | |
| ++  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
 | |
| ++  UInt32 alignPrices[kAlignTableSize];
 | |
| ++  UInt32 alignPriceCount;
 | |
| ++
 | |
| ++  UInt32 distTableSize;
 | |
| ++
 | |
| ++  unsigned lc, lp, pb;
 | |
| ++  unsigned lpMask, pbMask;
 | |
| ++
 | |
| ++  CLzmaProb *litProbs;
 | |
| ++
 | |
| ++  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
 | |
| ++  CLzmaProb isRep[kNumStates];
 | |
| ++  CLzmaProb isRepG0[kNumStates];
 | |
| ++  CLzmaProb isRepG1[kNumStates];
 | |
| ++  CLzmaProb isRepG2[kNumStates];
 | |
| ++  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
 | |
| ++
 | |
| ++  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
 | |
| ++  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
 | |
| ++  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
 | |
| ++
 | |
| ++  CLenPriceEnc lenEnc;
 | |
| ++  CLenPriceEnc repLenEnc;
 | |
| ++
 | |
| ++  unsigned lclp;
 | |
| ++
 | |
| ++  Bool fastMode;
 | |
| ++
 | |
| ++  CRangeEnc rc;
 | |
| ++
 | |
| ++  Bool writeEndMark;
 | |
| ++  UInt64 nowPos64;
 | |
| ++  UInt32 matchPriceCount;
 | |
| ++  Bool finished;
 | |
| ++  Bool multiThread;
 | |
| ++
 | |
| ++  SRes result;
 | |
| ++  UInt32 dictSize;
 | |
| ++  UInt32 matchFinderCycles;
 | |
| ++
 | |
| ++  int needInit;
 | |
| ++
 | |
| ++  CSaveState saveState;
 | |
| ++} CLzmaEnc;
 | |
| ++
 | |
| ++void LzmaEnc_SaveState(CLzmaEncHandle pp)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  CSaveState *dest = &p->saveState;
 | |
| ++  int i;
 | |
| ++  dest->lenEnc = p->lenEnc;
 | |
| ++  dest->repLenEnc = p->repLenEnc;
 | |
| ++  dest->state = p->state;
 | |
| ++
 | |
| ++  for (i = 0; i < kNumStates; i++)
 | |
| ++  {
 | |
| ++    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
 | |
| ++    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
 | |
| ++  }
 | |
| ++  for (i = 0; i < kNumLenToPosStates; i++)
 | |
| ++    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
 | |
| ++  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
 | |
| ++  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
 | |
| ++  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
 | |
| ++  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
 | |
| ++  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
 | |
| ++  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
 | |
| ++  memcpy(dest->reps, p->reps, sizeof(p->reps));
 | |
| ++  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_RestoreState(CLzmaEncHandle pp)
 | |
| ++{
 | |
| ++  CLzmaEnc *dest = (CLzmaEnc *)pp;
 | |
| ++  const CSaveState *p = &dest->saveState;
 | |
| ++  int i;
 | |
| ++  dest->lenEnc = p->lenEnc;
 | |
| ++  dest->repLenEnc = p->repLenEnc;
 | |
| ++  dest->state = p->state;
 | |
| ++
 | |
| ++  for (i = 0; i < kNumStates; i++)
 | |
| ++  {
 | |
| ++    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
 | |
| ++    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
 | |
| ++  }
 | |
| ++  for (i = 0; i < kNumLenToPosStates; i++)
 | |
| ++    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
 | |
| ++  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
 | |
| ++  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
 | |
| ++  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
 | |
| ++  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
 | |
| ++  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
 | |
| ++  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
 | |
| ++  memcpy(dest->reps, p->reps, sizeof(p->reps));
 | |
| ++  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  CLzmaEncProps props = *props2;
 | |
| ++  LzmaEncProps_Normalize(&props);
 | |
| ++
 | |
| ++  if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
 | |
| ++      props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
 | |
| ++    return SZ_ERROR_PARAM;
 | |
| ++  p->dictSize = props.dictSize;
 | |
| ++  p->matchFinderCycles = props.mc;
 | |
| ++  {
 | |
| ++    unsigned fb = props.fb;
 | |
| ++    if (fb < 5)
 | |
| ++      fb = 5;
 | |
| ++    if (fb > LZMA_MATCH_LEN_MAX)
 | |
| ++      fb = LZMA_MATCH_LEN_MAX;
 | |
| ++    p->numFastBytes = fb;
 | |
| ++  }
 | |
| ++  p->lc = props.lc;
 | |
| ++  p->lp = props.lp;
 | |
| ++  p->pb = props.pb;
 | |
| ++  p->fastMode = (props.algo == 0);
 | |
| ++  p->matchFinderBase.btMode = props.btMode;
 | |
| ++  {
 | |
| ++    UInt32 numHashBytes = 4;
 | |
| ++    if (props.btMode)
 | |
| ++    {
 | |
| ++      if (props.numHashBytes < 2)
 | |
| ++        numHashBytes = 2;
 | |
| ++      else if (props.numHashBytes < 4)
 | |
| ++        numHashBytes = props.numHashBytes;
 | |
| ++    }
 | |
| ++    p->matchFinderBase.numHashBytes = numHashBytes;
 | |
| ++  }
 | |
| ++
 | |
| ++  p->matchFinderBase.cutValue = props.mc;
 | |
| ++
 | |
| ++  p->writeEndMark = props.writeEndMark;
 | |
| ++
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  /*
 | |
| ++  if (newMultiThread != _multiThread)
 | |
| ++  {
 | |
| ++    ReleaseMatchFinder();
 | |
| ++    _multiThread = newMultiThread;
 | |
| ++  }
 | |
| ++  */
 | |
| ++  p->multiThread = (props.numThreads > 1);
 | |
| ++  #endif
 | |
| ++
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
 | |
| ++static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
 | |
| ++static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
 | |
| ++static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
 | |
| ++
 | |
| ++#define IsCharState(s) ((s) < 7)
 | |
| ++
 | |
| ++#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
 | |
| ++
 | |
| ++#define kInfinityPrice (1 << 30)
 | |
| ++
 | |
| ++static void RangeEnc_Construct(CRangeEnc *p)
 | |
| ++{
 | |
| ++  p->outStream = 0;
 | |
| ++  p->bufBase = 0;
 | |
| ++}
 | |
| ++
 | |
| ++#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
 | |
| ++
 | |
| ++#define RC_BUF_SIZE (1 << 16)
 | |
| ++static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  if (p->bufBase == 0)
 | |
| ++  {
 | |
| ++    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
 | |
| ++    if (p->bufBase == 0)
 | |
| ++      return 0;
 | |
| ++    p->bufLim = p->bufBase + RC_BUF_SIZE;
 | |
| ++  }
 | |
| ++  return 1;
 | |
| ++}
 | |
| ++
 | |
| ++static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  alloc->Free(alloc, p->bufBase);
 | |
| ++  p->bufBase = 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void RangeEnc_Init(CRangeEnc *p)
 | |
| ++{
 | |
| ++  /* Stream.Init(); */
 | |
| ++  p->low = 0;
 | |
| ++  p->range = 0xFFFFFFFF;
 | |
| ++  p->cacheSize = 1;
 | |
| ++  p->cache = 0;
 | |
| ++
 | |
| ++  p->buf = p->bufBase;
 | |
| ++
 | |
| ++  p->processed = 0;
 | |
| ++  p->res = SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++static void RangeEnc_FlushStream(CRangeEnc *p)
 | |
| ++{
 | |
| ++  size_t num;
 | |
| ++  if (p->res != SZ_OK)
 | |
| ++    return;
 | |
| ++  num = p->buf - p->bufBase;
 | |
| ++  if (num != p->outStream->Write(p->outStream, p->bufBase, num))
 | |
| ++    p->res = SZ_ERROR_WRITE;
 | |
| ++  p->processed += num;
 | |
| ++  p->buf = p->bufBase;
 | |
| ++}
 | |
| ++
 | |
| ++static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
 | |
| ++{
 | |
| ++  if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
 | |
| ++  {
 | |
| ++    Byte temp = p->cache;
 | |
| ++    do
 | |
| ++    {
 | |
| ++      Byte *buf = p->buf;
 | |
| ++      *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
 | |
| ++      p->buf = buf;
 | |
| ++      if (buf == p->bufLim)
 | |
| ++        RangeEnc_FlushStream(p);
 | |
| ++      temp = 0xFF;
 | |
| ++    }
 | |
| ++    while (--p->cacheSize != 0);
 | |
| ++    p->cache = (Byte)((UInt32)p->low >> 24);
 | |
| ++  }
 | |
| ++  p->cacheSize++;
 | |
| ++  p->low = (UInt32)p->low << 8;
 | |
| ++}
 | |
| ++
 | |
| ++static void RangeEnc_FlushData(CRangeEnc *p)
 | |
| ++{
 | |
| ++  int i;
 | |
| ++  for (i = 0; i < 5; i++)
 | |
| ++    RangeEnc_ShiftLow(p);
 | |
| ++}
 | |
| ++
 | |
| ++static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
 | |
| ++{
 | |
| ++  do
 | |
| ++  {
 | |
| ++    p->range >>= 1;
 | |
| ++    p->low += p->range & (0 - ((value >> --numBits) & 1));
 | |
| ++    if (p->range < kTopValue)
 | |
| ++    {
 | |
| ++      p->range <<= 8;
 | |
| ++      RangeEnc_ShiftLow(p);
 | |
| ++    }
 | |
| ++  }
 | |
| ++  while (numBits != 0);
 | |
| ++}
 | |
| ++
 | |
| ++static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
 | |
| ++{
 | |
| ++  UInt32 ttt = *prob;
 | |
| ++  UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
 | |
| ++  if (symbol == 0)
 | |
| ++  {
 | |
| ++    p->range = newBound;
 | |
| ++    ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
 | |
| ++  }
 | |
| ++  else
 | |
| ++  {
 | |
| ++    p->low += newBound;
 | |
| ++    p->range -= newBound;
 | |
| ++    ttt -= ttt >> kNumMoveBits;
 | |
| ++  }
 | |
| ++  *prob = (CLzmaProb)ttt;
 | |
| ++  if (p->range < kTopValue)
 | |
| ++  {
 | |
| ++    p->range <<= 8;
 | |
| ++    RangeEnc_ShiftLow(p);
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
 | |
| ++{
 | |
| ++  symbol |= 0x100;
 | |
| ++  do
 | |
| ++  {
 | |
| ++    RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
 | |
| ++    symbol <<= 1;
 | |
| ++  }
 | |
| ++  while (symbol < 0x10000);
 | |
| ++}
 | |
| ++
 | |
| ++static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
 | |
| ++{
 | |
| ++  UInt32 offs = 0x100;
 | |
| ++  symbol |= 0x100;
 | |
| ++  do
 | |
| ++  {
 | |
| ++    matchByte <<= 1;
 | |
| ++    RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
 | |
| ++    symbol <<= 1;
 | |
| ++    offs &= ~(matchByte ^ symbol);
 | |
| ++  }
 | |
| ++  while (symbol < 0x10000);
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  UInt32 i;
 | |
| ++  for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
 | |
| ++  {
 | |
| ++    const int kCyclesBits = kNumBitPriceShiftBits;
 | |
| ++    UInt32 w = i;
 | |
| ++    UInt32 bitCount = 0;
 | |
| ++    int j;
 | |
| ++    for (j = 0; j < kCyclesBits; j++)
 | |
| ++    {
 | |
| ++      w = w * w;
 | |
| ++      bitCount <<= 1;
 | |
| ++      while (w >= ((UInt32)1 << 16))
 | |
| ++      {
 | |
| ++        w >>= 1;
 | |
| ++        bitCount++;
 | |
| ++      }
 | |
| ++    }
 | |
| ++    ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++#define GET_PRICE(prob, symbol) \
 | |
| ++  p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
 | |
| ++
 | |
| ++#define GET_PRICEa(prob, symbol) \
 | |
| ++  ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
 | |
| ++
 | |
| ++#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
 | |
| ++#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
 | |
| ++
 | |
| ++#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
 | |
| ++#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
 | |
| ++
 | |
| ++static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  UInt32 price = 0;
 | |
| ++  symbol |= 0x100;
 | |
| ++  do
 | |
| ++  {
 | |
| ++    price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
 | |
| ++    symbol <<= 1;
 | |
| ++  }
 | |
| ++  while (symbol < 0x10000);
 | |
| ++  return price;
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  UInt32 price = 0;
 | |
| ++  UInt32 offs = 0x100;
 | |
| ++  symbol |= 0x100;
 | |
| ++  do
 | |
| ++  {
 | |
| ++    matchByte <<= 1;
 | |
| ++    price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
 | |
| ++    symbol <<= 1;
 | |
| ++    offs &= ~(matchByte ^ symbol);
 | |
| ++  }
 | |
| ++  while (symbol < 0x10000);
 | |
| ++  return price;
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
 | |
| ++{
 | |
| ++  UInt32 m = 1;
 | |
| ++  int i;
 | |
| ++  for (i = numBitLevels; i != 0;)
 | |
| ++  {
 | |
| ++    UInt32 bit;
 | |
| ++    i--;
 | |
| ++    bit = (symbol >> i) & 1;
 | |
| ++    RangeEnc_EncodeBit(rc, probs + m, bit);
 | |
| ++    m = (m << 1) | bit;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
 | |
| ++{
 | |
| ++  UInt32 m = 1;
 | |
| ++  int i;
 | |
| ++  for (i = 0; i < numBitLevels; i++)
 | |
| ++  {
 | |
| ++    UInt32 bit = symbol & 1;
 | |
| ++    RangeEnc_EncodeBit(rc, probs + m, bit);
 | |
| ++    m = (m << 1) | bit;
 | |
| ++    symbol >>= 1;
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  UInt32 price = 0;
 | |
| ++  symbol |= (1 << numBitLevels);
 | |
| ++  while (symbol != 1)
 | |
| ++  {
 | |
| ++    price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
 | |
| ++    symbol >>= 1;
 | |
| ++  }
 | |
| ++  return price;
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  UInt32 price = 0;
 | |
| ++  UInt32 m = 1;
 | |
| ++  int i;
 | |
| ++  for (i = numBitLevels; i != 0; i--)
 | |
| ++  {
 | |
| ++    UInt32 bit = symbol & 1;
 | |
| ++    symbol >>= 1;
 | |
| ++    price += GET_PRICEa(probs[m], bit);
 | |
| ++    m = (m << 1) | bit;
 | |
| ++  }
 | |
| ++  return price;
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++static void LenEnc_Init(CLenEnc *p)
 | |
| ++{
 | |
| ++  unsigned i;
 | |
| ++  p->choice = p->choice2 = kProbInitValue;
 | |
| ++  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
 | |
| ++    p->low[i] = kProbInitValue;
 | |
| ++  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
 | |
| ++    p->mid[i] = kProbInitValue;
 | |
| ++  for (i = 0; i < kLenNumHighSymbols; i++)
 | |
| ++    p->high[i] = kProbInitValue;
 | |
| ++}
 | |
| ++
 | |
| ++static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
 | |
| ++{
 | |
| ++  if (symbol < kLenNumLowSymbols)
 | |
| ++  {
 | |
| ++    RangeEnc_EncodeBit(rc, &p->choice, 0);
 | |
| ++    RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
 | |
| ++  }
 | |
| ++  else
 | |
| ++  {
 | |
| ++    RangeEnc_EncodeBit(rc, &p->choice, 1);
 | |
| ++    if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
 | |
| ++    {
 | |
| ++      RangeEnc_EncodeBit(rc, &p->choice2, 0);
 | |
| ++      RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
 | |
| ++    }
 | |
| ++    else
 | |
| ++    {
 | |
| ++      RangeEnc_EncodeBit(rc, &p->choice2, 1);
 | |
| ++      RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
 | |
| ++    }
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  UInt32 a0 = GET_PRICE_0a(p->choice);
 | |
| ++  UInt32 a1 = GET_PRICE_1a(p->choice);
 | |
| ++  UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
 | |
| ++  UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
 | |
| ++  UInt32 i = 0;
 | |
| ++  for (i = 0; i < kLenNumLowSymbols; i++)
 | |
| ++  {
 | |
| ++    if (i >= numSymbols)
 | |
| ++      return;
 | |
| ++    prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
 | |
| ++  }
 | |
| ++  for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
 | |
| ++  {
 | |
| ++    if (i >= numSymbols)
 | |
| ++      return;
 | |
| ++    prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
 | |
| ++  }
 | |
| ++  for (; i < numSymbols; i++)
 | |
| ++    prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
 | |
| ++}
 | |
| ++
 | |
| ++static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
 | |
| ++  p->counters[posState] = p->tableSize;
 | |
| ++}
 | |
| ++
 | |
| ++static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  UInt32 posState;
 | |
| ++  for (posState = 0; posState < numPosStates; posState++)
 | |
| ++    LenPriceEnc_UpdateTable(p, posState, ProbPrices);
 | |
| ++}
 | |
| ++
 | |
| ++static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
 | |
| ++{
 | |
| ++  LenEnc_Encode(&p->p, rc, symbol, posState);
 | |
| ++  if (updatePrice)
 | |
| ++    if (--p->counters[posState] == 0)
 | |
| ++      LenPriceEnc_UpdateTable(p, posState, ProbPrices);
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++
 | |
| ++
 | |
| ++static void MovePos(CLzmaEnc *p, UInt32 num)
 | |
| ++{
 | |
| ++  #ifdef SHOW_STAT
 | |
| ++  ttt += num;
 | |
| ++  printf("\n MovePos %d", num);
 | |
| ++  #endif
 | |
| ++  if (num != 0)
 | |
| ++  {
 | |
| ++    p->additionalOffset += num;
 | |
| ++    p->matchFinder.Skip(p->matchFinderObj, num);
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
 | |
| ++{
 | |
| ++  UInt32 lenRes = 0, numPairs;
 | |
| ++  p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
 | |
| ++  numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
 | |
| ++  #ifdef SHOW_STAT
 | |
| ++  printf("\n i = %d numPairs = %d    ", ttt, numPairs / 2);
 | |
| ++  ttt++;
 | |
| ++  {
 | |
| ++    UInt32 i;
 | |
| ++    for (i = 0; i < numPairs; i += 2)
 | |
| ++      printf("%2d %6d   | ", p->matches[i], p->matches[i + 1]);
 | |
| ++  }
 | |
| ++  #endif
 | |
| ++  if (numPairs > 0)
 | |
| ++  {
 | |
| ++    lenRes = p->matches[numPairs - 2];
 | |
| ++    if (lenRes == p->numFastBytes)
 | |
| ++    {
 | |
| ++      const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
 | |
| ++      UInt32 distance = p->matches[numPairs - 1] + 1;
 | |
| ++      UInt32 numAvail = p->numAvail;
 | |
| ++      if (numAvail > LZMA_MATCH_LEN_MAX)
 | |
| ++        numAvail = LZMA_MATCH_LEN_MAX;
 | |
| ++      {
 | |
| ++        const Byte *pby2 = pby - distance;
 | |
| ++        for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++  p->additionalOffset++;
 | |
| ++  *numDistancePairsRes = numPairs;
 | |
| ++  return lenRes;
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
 | |
| ++#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
 | |
| ++#define IsShortRep(p) ((p)->backPrev == 0)
 | |
| ++
 | |
| ++static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
 | |
| ++{
 | |
| ++  return
 | |
| ++    GET_PRICE_0(p->isRepG0[state]) +
 | |
| ++    GET_PRICE_0(p->isRep0Long[state][posState]);
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
 | |
| ++{
 | |
| ++  UInt32 price;
 | |
| ++  if (repIndex == 0)
 | |
| ++  {
 | |
| ++    price = GET_PRICE_0(p->isRepG0[state]);
 | |
| ++    price += GET_PRICE_1(p->isRep0Long[state][posState]);
 | |
| ++  }
 | |
| ++  else
 | |
| ++  {
 | |
| ++    price = GET_PRICE_1(p->isRepG0[state]);
 | |
| ++    if (repIndex == 1)
 | |
| ++      price += GET_PRICE_0(p->isRepG1[state]);
 | |
| ++    else
 | |
| ++    {
 | |
| ++      price += GET_PRICE_1(p->isRepG1[state]);
 | |
| ++      price += GET_PRICE(p->isRepG2[state], repIndex - 2);
 | |
| ++    }
 | |
| ++  }
 | |
| ++  return price;
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
 | |
| ++{
 | |
| ++  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
 | |
| ++    GetPureRepPrice(p, repIndex, state, posState);
 | |
| ++}
 | |
| ++
 | |
| ++static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
 | |
| ++{
 | |
| ++  UInt32 posMem = p->opt[cur].posPrev;
 | |
| ++  UInt32 backMem = p->opt[cur].backPrev;
 | |
| ++  p->optimumEndIndex = cur;
 | |
| ++  do
 | |
| ++  {
 | |
| ++    if (p->opt[cur].prev1IsChar)
 | |
| ++    {
 | |
| ++      MakeAsChar(&p->opt[posMem])
 | |
| ++      p->opt[posMem].posPrev = posMem - 1;
 | |
| ++      if (p->opt[cur].prev2)
 | |
| ++      {
 | |
| ++        p->opt[posMem - 1].prev1IsChar = False;
 | |
| ++        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
 | |
| ++        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
 | |
| ++      }
 | |
| ++    }
 | |
| ++    {
 | |
| ++      UInt32 posPrev = posMem;
 | |
| ++      UInt32 backCur = backMem;
 | |
| ++
 | |
| ++      backMem = p->opt[posPrev].backPrev;
 | |
| ++      posMem = p->opt[posPrev].posPrev;
 | |
| ++
 | |
| ++      p->opt[posPrev].backPrev = backCur;
 | |
| ++      p->opt[posPrev].posPrev = cur;
 | |
| ++      cur = posPrev;
 | |
| ++    }
 | |
| ++  }
 | |
| ++  while (cur != 0);
 | |
| ++  *backRes = p->opt[0].backPrev;
 | |
| ++  p->optimumCurrentIndex  = p->opt[0].posPrev;
 | |
| ++  return p->optimumCurrentIndex;
 | |
| ++}
 | |
| ++
 | |
| ++#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
 | |
| ++
 | |
| ++static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
 | |
| ++{
 | |
| ++  UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
 | |
| ++  UInt32 matchPrice, repMatchPrice, normalMatchPrice;
 | |
| ++  UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
 | |
| ++  UInt32 *matches;
 | |
| ++  const Byte *data;
 | |
| ++  Byte curByte, matchByte;
 | |
| ++  if (p->optimumEndIndex != p->optimumCurrentIndex)
 | |
| ++  {
 | |
| ++    const COptimal *opt = &p->opt[p->optimumCurrentIndex];
 | |
| ++    UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
 | |
| ++    *backRes = opt->backPrev;
 | |
| ++    p->optimumCurrentIndex = opt->posPrev;
 | |
| ++    return lenRes;
 | |
| ++  }
 | |
| ++  p->optimumCurrentIndex = p->optimumEndIndex = 0;
 | |
| ++
 | |
| ++  if (p->additionalOffset == 0)
 | |
| ++    mainLen = ReadMatchDistances(p, &numPairs);
 | |
| ++  else
 | |
| ++  {
 | |
| ++    mainLen = p->longestMatchLength;
 | |
| ++    numPairs = p->numPairs;
 | |
| ++  }
 | |
| ++
 | |
| ++  numAvail = p->numAvail;
 | |
| ++  if (numAvail < 2)
 | |
| ++  {
 | |
| ++    *backRes = (UInt32)(-1);
 | |
| ++    return 1;
 | |
| ++  }
 | |
| ++  if (numAvail > LZMA_MATCH_LEN_MAX)
 | |
| ++    numAvail = LZMA_MATCH_LEN_MAX;
 | |
| ++
 | |
| ++  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
 | |
| ++  repMaxIndex = 0;
 | |
| ++  for (i = 0; i < LZMA_NUM_REPS; i++)
 | |
| ++  {
 | |
| ++    UInt32 lenTest;
 | |
| ++    const Byte *data2;
 | |
| ++    reps[i] = p->reps[i];
 | |
| ++    data2 = data - (reps[i] + 1);
 | |
| ++    if (data[0] != data2[0] || data[1] != data2[1])
 | |
| ++    {
 | |
| ++      repLens[i] = 0;
 | |
| ++      continue;
 | |
| ++    }
 | |
| ++    for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
 | |
| ++    repLens[i] = lenTest;
 | |
| ++    if (lenTest > repLens[repMaxIndex])
 | |
| ++      repMaxIndex = i;
 | |
| ++  }
 | |
| ++  if (repLens[repMaxIndex] >= p->numFastBytes)
 | |
| ++  {
 | |
| ++    UInt32 lenRes;
 | |
| ++    *backRes = repMaxIndex;
 | |
| ++    lenRes = repLens[repMaxIndex];
 | |
| ++    MovePos(p, lenRes - 1);
 | |
| ++    return lenRes;
 | |
| ++  }
 | |
| ++
 | |
| ++  matches = p->matches;
 | |
| ++  if (mainLen >= p->numFastBytes)
 | |
| ++  {
 | |
| ++    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
 | |
| ++    MovePos(p, mainLen - 1);
 | |
| ++    return mainLen;
 | |
| ++  }
 | |
| ++  curByte = *data;
 | |
| ++  matchByte = *(data - (reps[0] + 1));
 | |
| ++
 | |
| ++  if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
 | |
| ++  {
 | |
| ++    *backRes = (UInt32)-1;
 | |
| ++    return 1;
 | |
| ++  }
 | |
| ++
 | |
| ++  p->opt[0].state = (CState)p->state;
 | |
| ++
 | |
| ++  posState = (position & p->pbMask);
 | |
| ++
 | |
| ++  {
 | |
| ++    const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
 | |
| ++    p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
 | |
| ++        (!IsCharState(p->state) ?
 | |
| ++          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
 | |
| ++          LitEnc_GetPrice(probs, curByte, p->ProbPrices));
 | |
| ++  }
 | |
| ++
 | |
| ++  MakeAsChar(&p->opt[1]);
 | |
| ++
 | |
| ++  matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
 | |
| ++  repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
 | |
| ++
 | |
| ++  if (matchByte == curByte)
 | |
| ++  {
 | |
| ++    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
 | |
| ++    if (shortRepPrice < p->opt[1].price)
 | |
| ++    {
 | |
| ++      p->opt[1].price = shortRepPrice;
 | |
| ++      MakeAsShortRep(&p->opt[1]);
 | |
| ++    }
 | |
| ++  }
 | |
| ++  lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
 | |
| ++
 | |
| ++  if (lenEnd < 2)
 | |
| ++  {
 | |
| ++    *backRes = p->opt[1].backPrev;
 | |
| ++    return 1;
 | |
| ++  }
 | |
| ++
 | |
| ++  p->opt[1].posPrev = 0;
 | |
| ++  for (i = 0; i < LZMA_NUM_REPS; i++)
 | |
| ++    p->opt[0].backs[i] = reps[i];
 | |
| ++
 | |
| ++  len = lenEnd;
 | |
| ++  do
 | |
| ++    p->opt[len--].price = kInfinityPrice;
 | |
| ++  while (len >= 2);
 | |
| ++
 | |
| ++  for (i = 0; i < LZMA_NUM_REPS; i++)
 | |
| ++  {
 | |
| ++    UInt32 repLen = repLens[i];
 | |
| ++    UInt32 price;
 | |
| ++    if (repLen < 2)
 | |
| ++      continue;
 | |
| ++    price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
 | |
| ++    do
 | |
| ++    {
 | |
| ++      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
 | |
| ++      COptimal *opt = &p->opt[repLen];
 | |
| ++      if (curAndLenPrice < opt->price)
 | |
| ++      {
 | |
| ++        opt->price = curAndLenPrice;
 | |
| ++        opt->posPrev = 0;
 | |
| ++        opt->backPrev = i;
 | |
| ++        opt->prev1IsChar = False;
 | |
| ++      }
 | |
| ++    }
 | |
| ++    while (--repLen >= 2);
 | |
| ++  }
 | |
| ++
 | |
| ++  normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
 | |
| ++
 | |
| ++  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
 | |
| ++  if (len <= mainLen)
 | |
| ++  {
 | |
| ++    UInt32 offs = 0;
 | |
| ++    while (len > matches[offs])
 | |
| ++      offs += 2;
 | |
| ++    for (; ; len++)
 | |
| ++    {
 | |
| ++      COptimal *opt;
 | |
| ++      UInt32 distance = matches[offs + 1];
 | |
| ++
 | |
| ++      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
 | |
| ++      UInt32 lenToPosState = GetLenToPosState(len);
 | |
| ++      if (distance < kNumFullDistances)
 | |
| ++        curAndLenPrice += p->distancesPrices[lenToPosState][distance];
 | |
| ++      else
 | |
| ++      {
 | |
| ++        UInt32 slot;
 | |
| ++        GetPosSlot2(distance, slot);
 | |
| ++        curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
 | |
| ++      }
 | |
| ++      opt = &p->opt[len];
 | |
| ++      if (curAndLenPrice < opt->price)
 | |
| ++      {
 | |
| ++        opt->price = curAndLenPrice;
 | |
| ++        opt->posPrev = 0;
 | |
| ++        opt->backPrev = distance + LZMA_NUM_REPS;
 | |
| ++        opt->prev1IsChar = False;
 | |
| ++      }
 | |
| ++      if (len == matches[offs])
 | |
| ++      {
 | |
| ++        offs += 2;
 | |
| ++        if (offs == numPairs)
 | |
| ++          break;
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++
 | |
| ++  cur = 0;
 | |
| ++
 | |
| ++    #ifdef SHOW_STAT2
 | |
| ++    if (position >= 0)
 | |
| ++    {
 | |
| ++      unsigned i;
 | |
| ++      printf("\n pos = %4X", position);
 | |
| ++      for (i = cur; i <= lenEnd; i++)
 | |
| ++      printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
 | |
| ++    }
 | |
| ++    #endif
 | |
| ++
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
 | |
| ++    UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
 | |
| ++    Bool nextIsChar;
 | |
| ++    Byte curByte, matchByte;
 | |
| ++    const Byte *data;
 | |
| ++    COptimal *curOpt;
 | |
| ++    COptimal *nextOpt;
 | |
| ++
 | |
| ++    cur++;
 | |
| ++    if (cur == lenEnd)
 | |
| ++      return Backward(p, backRes, cur);
 | |
| ++
 | |
| ++    newLen = ReadMatchDistances(p, &numPairs);
 | |
| ++    if (newLen >= p->numFastBytes)
 | |
| ++    {
 | |
| ++      p->numPairs = numPairs;
 | |
| ++      p->longestMatchLength = newLen;
 | |
| ++      return Backward(p, backRes, cur);
 | |
| ++    }
 | |
| ++    position++;
 | |
| ++    curOpt = &p->opt[cur];
 | |
| ++    posPrev = curOpt->posPrev;
 | |
| ++    if (curOpt->prev1IsChar)
 | |
| ++    {
 | |
| ++      posPrev--;
 | |
| ++      if (curOpt->prev2)
 | |
| ++      {
 | |
| ++        state = p->opt[curOpt->posPrev2].state;
 | |
| ++        if (curOpt->backPrev2 < LZMA_NUM_REPS)
 | |
| ++          state = kRepNextStates[state];
 | |
| ++        else
 | |
| ++          state = kMatchNextStates[state];
 | |
| ++      }
 | |
| ++      else
 | |
| ++        state = p->opt[posPrev].state;
 | |
| ++      state = kLiteralNextStates[state];
 | |
| ++    }
 | |
| ++    else
 | |
| ++      state = p->opt[posPrev].state;
 | |
| ++    if (posPrev == cur - 1)
 | |
| ++    {
 | |
| ++      if (IsShortRep(curOpt))
 | |
| ++        state = kShortRepNextStates[state];
 | |
| ++      else
 | |
| ++        state = kLiteralNextStates[state];
 | |
| ++    }
 | |
| ++    else
 | |
| ++    {
 | |
| ++      UInt32 pos;
 | |
| ++      const COptimal *prevOpt;
 | |
| ++      if (curOpt->prev1IsChar && curOpt->prev2)
 | |
| ++      {
 | |
| ++        posPrev = curOpt->posPrev2;
 | |
| ++        pos = curOpt->backPrev2;
 | |
| ++        state = kRepNextStates[state];
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        pos = curOpt->backPrev;
 | |
| ++        if (pos < LZMA_NUM_REPS)
 | |
| ++          state = kRepNextStates[state];
 | |
| ++        else
 | |
| ++          state = kMatchNextStates[state];
 | |
| ++      }
 | |
| ++      prevOpt = &p->opt[posPrev];
 | |
| ++      if (pos < LZMA_NUM_REPS)
 | |
| ++      {
 | |
| ++        UInt32 i;
 | |
| ++        reps[0] = prevOpt->backs[pos];
 | |
| ++        for (i = 1; i <= pos; i++)
 | |
| ++          reps[i] = prevOpt->backs[i - 1];
 | |
| ++        for (; i < LZMA_NUM_REPS; i++)
 | |
| ++          reps[i] = prevOpt->backs[i];
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        UInt32 i;
 | |
| ++        reps[0] = (pos - LZMA_NUM_REPS);
 | |
| ++        for (i = 1; i < LZMA_NUM_REPS; i++)
 | |
| ++          reps[i] = prevOpt->backs[i - 1];
 | |
| ++      }
 | |
| ++    }
 | |
| ++    curOpt->state = (CState)state;
 | |
| ++
 | |
| ++    curOpt->backs[0] = reps[0];
 | |
| ++    curOpt->backs[1] = reps[1];
 | |
| ++    curOpt->backs[2] = reps[2];
 | |
| ++    curOpt->backs[3] = reps[3];
 | |
| ++
 | |
| ++    curPrice = curOpt->price;
 | |
| ++    nextIsChar = False;
 | |
| ++    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
 | |
| ++    curByte = *data;
 | |
| ++    matchByte = *(data - (reps[0] + 1));
 | |
| ++
 | |
| ++    posState = (position & p->pbMask);
 | |
| ++
 | |
| ++    curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
 | |
| ++    {
 | |
| ++      const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
 | |
| ++      curAnd1Price +=
 | |
| ++        (!IsCharState(state) ?
 | |
| ++          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
 | |
| ++          LitEnc_GetPrice(probs, curByte, p->ProbPrices));
 | |
| ++    }
 | |
| ++
 | |
| ++    nextOpt = &p->opt[cur + 1];
 | |
| ++
 | |
| ++    if (curAnd1Price < nextOpt->price)
 | |
| ++    {
 | |
| ++      nextOpt->price = curAnd1Price;
 | |
| ++      nextOpt->posPrev = cur;
 | |
| ++      MakeAsChar(nextOpt);
 | |
| ++      nextIsChar = True;
 | |
| ++    }
 | |
| ++
 | |
| ++    matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
 | |
| ++    repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
 | |
| ++
 | |
| ++    if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
 | |
| ++    {
 | |
| ++      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
 | |
| ++      if (shortRepPrice <= nextOpt->price)
 | |
| ++      {
 | |
| ++        nextOpt->price = shortRepPrice;
 | |
| ++        nextOpt->posPrev = cur;
 | |
| ++        MakeAsShortRep(nextOpt);
 | |
| ++        nextIsChar = True;
 | |
| ++      }
 | |
| ++    }
 | |
| ++    numAvailFull = p->numAvail;
 | |
| ++    {
 | |
| ++      UInt32 temp = kNumOpts - 1 - cur;
 | |
| ++      if (temp < numAvailFull)
 | |
| ++        numAvailFull = temp;
 | |
| ++    }
 | |
| ++
 | |
| ++    if (numAvailFull < 2)
 | |
| ++      continue;
 | |
| ++    numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
 | |
| ++
 | |
| ++    if (!nextIsChar && matchByte != curByte) /* speed optimization */
 | |
| ++    {
 | |
| ++      /* try Literal + rep0 */
 | |
| ++      UInt32 temp;
 | |
| ++      UInt32 lenTest2;
 | |
| ++      const Byte *data2 = data - (reps[0] + 1);
 | |
| ++      UInt32 limit = p->numFastBytes + 1;
 | |
| ++      if (limit > numAvailFull)
 | |
| ++        limit = numAvailFull;
 | |
| ++
 | |
| ++      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
 | |
| ++      lenTest2 = temp - 1;
 | |
| ++      if (lenTest2 >= 2)
 | |
| ++      {
 | |
| ++        UInt32 state2 = kLiteralNextStates[state];
 | |
| ++        UInt32 posStateNext = (position + 1) & p->pbMask;
 | |
| ++        UInt32 nextRepMatchPrice = curAnd1Price +
 | |
| ++            GET_PRICE_1(p->isMatch[state2][posStateNext]) +
 | |
| ++            GET_PRICE_1(p->isRep[state2]);
 | |
| ++        /* for (; lenTest2 >= 2; lenTest2--) */
 | |
| ++        {
 | |
| ++          UInt32 curAndLenPrice;
 | |
| ++          COptimal *opt;
 | |
| ++          UInt32 offset = cur + 1 + lenTest2;
 | |
| ++          while (lenEnd < offset)
 | |
| ++            p->opt[++lenEnd].price = kInfinityPrice;
 | |
| ++          curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
 | |
| ++          opt = &p->opt[offset];
 | |
| ++          if (curAndLenPrice < opt->price)
 | |
| ++          {
 | |
| ++            opt->price = curAndLenPrice;
 | |
| ++            opt->posPrev = cur + 1;
 | |
| ++            opt->backPrev = 0;
 | |
| ++            opt->prev1IsChar = True;
 | |
| ++            opt->prev2 = False;
 | |
| ++          }
 | |
| ++        }
 | |
| ++      }
 | |
| ++    }
 | |
| ++
 | |
| ++    startLen = 2; /* speed optimization */
 | |
| ++    {
 | |
| ++    UInt32 repIndex;
 | |
| ++    for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
 | |
| ++    {
 | |
| ++      UInt32 lenTest;
 | |
| ++      UInt32 lenTestTemp;
 | |
| ++      UInt32 price;
 | |
| ++      const Byte *data2 = data - (reps[repIndex] + 1);
 | |
| ++      if (data[0] != data2[0] || data[1] != data2[1])
 | |
| ++        continue;
 | |
| ++      for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
 | |
| ++      while (lenEnd < cur + lenTest)
 | |
| ++        p->opt[++lenEnd].price = kInfinityPrice;
 | |
| ++      lenTestTemp = lenTest;
 | |
| ++      price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
 | |
| ++      do
 | |
| ++      {
 | |
| ++        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
 | |
| ++        COptimal *opt = &p->opt[cur + lenTest];
 | |
| ++        if (curAndLenPrice < opt->price)
 | |
| ++        {
 | |
| ++          opt->price = curAndLenPrice;
 | |
| ++          opt->posPrev = cur;
 | |
| ++          opt->backPrev = repIndex;
 | |
| ++          opt->prev1IsChar = False;
 | |
| ++        }
 | |
| ++      }
 | |
| ++      while (--lenTest >= 2);
 | |
| ++      lenTest = lenTestTemp;
 | |
| ++
 | |
| ++      if (repIndex == 0)
 | |
| ++        startLen = lenTest + 1;
 | |
| ++
 | |
| ++      /* if (_maxMode) */
 | |
| ++        {
 | |
| ++          UInt32 lenTest2 = lenTest + 1;
 | |
| ++          UInt32 limit = lenTest2 + p->numFastBytes;
 | |
| ++          UInt32 nextRepMatchPrice;
 | |
| ++          if (limit > numAvailFull)
 | |
| ++            limit = numAvailFull;
 | |
| ++          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
 | |
| ++          lenTest2 -= lenTest + 1;
 | |
| ++          if (lenTest2 >= 2)
 | |
| ++          {
 | |
| ++            UInt32 state2 = kRepNextStates[state];
 | |
| ++            UInt32 posStateNext = (position + lenTest) & p->pbMask;
 | |
| ++            UInt32 curAndLenCharPrice =
 | |
| ++                price + p->repLenEnc.prices[posState][lenTest - 2] +
 | |
| ++                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
 | |
| ++                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
 | |
| ++                    data[lenTest], data2[lenTest], p->ProbPrices);
 | |
| ++            state2 = kLiteralNextStates[state2];
 | |
| ++            posStateNext = (position + lenTest + 1) & p->pbMask;
 | |
| ++            nextRepMatchPrice = curAndLenCharPrice +
 | |
| ++                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
 | |
| ++                GET_PRICE_1(p->isRep[state2]);
 | |
| ++
 | |
| ++            /* for (; lenTest2 >= 2; lenTest2--) */
 | |
| ++            {
 | |
| ++              UInt32 curAndLenPrice;
 | |
| ++              COptimal *opt;
 | |
| ++              UInt32 offset = cur + lenTest + 1 + lenTest2;
 | |
| ++              while (lenEnd < offset)
 | |
| ++                p->opt[++lenEnd].price = kInfinityPrice;
 | |
| ++              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
 | |
| ++              opt = &p->opt[offset];
 | |
| ++              if (curAndLenPrice < opt->price)
 | |
| ++              {
 | |
| ++                opt->price = curAndLenPrice;
 | |
| ++                opt->posPrev = cur + lenTest + 1;
 | |
| ++                opt->backPrev = 0;
 | |
| ++                opt->prev1IsChar = True;
 | |
| ++                opt->prev2 = True;
 | |
| ++                opt->posPrev2 = cur;
 | |
| ++                opt->backPrev2 = repIndex;
 | |
| ++              }
 | |
| ++            }
 | |
| ++          }
 | |
| ++        }
 | |
| ++    }
 | |
| ++    }
 | |
| ++    /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
 | |
| ++    if (newLen > numAvail)
 | |
| ++    {
 | |
| ++      newLen = numAvail;
 | |
| ++      for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
 | |
| ++      matches[numPairs] = newLen;
 | |
| ++      numPairs += 2;
 | |
| ++    }
 | |
| ++    if (newLen >= startLen)
 | |
| ++    {
 | |
| ++      UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
 | |
| ++      UInt32 offs, curBack, posSlot;
 | |
| ++      UInt32 lenTest;
 | |
| ++      while (lenEnd < cur + newLen)
 | |
| ++        p->opt[++lenEnd].price = kInfinityPrice;
 | |
| ++
 | |
| ++      offs = 0;
 | |
| ++      while (startLen > matches[offs])
 | |
| ++        offs += 2;
 | |
| ++      curBack = matches[offs + 1];
 | |
| ++      GetPosSlot2(curBack, posSlot);
 | |
| ++      for (lenTest = /*2*/ startLen; ; lenTest++)
 | |
| ++      {
 | |
| ++        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
 | |
| ++        UInt32 lenToPosState = GetLenToPosState(lenTest);
 | |
| ++        COptimal *opt;
 | |
| ++        if (curBack < kNumFullDistances)
 | |
| ++          curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
 | |
| ++        else
 | |
| ++          curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
 | |
| ++
 | |
| ++        opt = &p->opt[cur + lenTest];
 | |
| ++        if (curAndLenPrice < opt->price)
 | |
| ++        {
 | |
| ++          opt->price = curAndLenPrice;
 | |
| ++          opt->posPrev = cur;
 | |
| ++          opt->backPrev = curBack + LZMA_NUM_REPS;
 | |
| ++          opt->prev1IsChar = False;
 | |
| ++        }
 | |
| ++
 | |
| ++        if (/*_maxMode && */lenTest == matches[offs])
 | |
| ++        {
 | |
| ++          /* Try Match + Literal + Rep0 */
 | |
| ++          const Byte *data2 = data - (curBack + 1);
 | |
| ++          UInt32 lenTest2 = lenTest + 1;
 | |
| ++          UInt32 limit = lenTest2 + p->numFastBytes;
 | |
| ++          UInt32 nextRepMatchPrice;
 | |
| ++          if (limit > numAvailFull)
 | |
| ++            limit = numAvailFull;
 | |
| ++          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
 | |
| ++          lenTest2 -= lenTest + 1;
 | |
| ++          if (lenTest2 >= 2)
 | |
| ++          {
 | |
| ++            UInt32 state2 = kMatchNextStates[state];
 | |
| ++            UInt32 posStateNext = (position + lenTest) & p->pbMask;
 | |
| ++            UInt32 curAndLenCharPrice = curAndLenPrice +
 | |
| ++                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
 | |
| ++                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
 | |
| ++                    data[lenTest], data2[lenTest], p->ProbPrices);
 | |
| ++            state2 = kLiteralNextStates[state2];
 | |
| ++            posStateNext = (posStateNext + 1) & p->pbMask;
 | |
| ++            nextRepMatchPrice = curAndLenCharPrice +
 | |
| ++                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
 | |
| ++                GET_PRICE_1(p->isRep[state2]);
 | |
| ++
 | |
| ++            /* for (; lenTest2 >= 2; lenTest2--) */
 | |
| ++            {
 | |
| ++              UInt32 offset = cur + lenTest + 1 + lenTest2;
 | |
| ++              UInt32 curAndLenPrice;
 | |
| ++              COptimal *opt;
 | |
| ++              while (lenEnd < offset)
 | |
| ++                p->opt[++lenEnd].price = kInfinityPrice;
 | |
| ++              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
 | |
| ++              opt = &p->opt[offset];
 | |
| ++              if (curAndLenPrice < opt->price)
 | |
| ++              {
 | |
| ++                opt->price = curAndLenPrice;
 | |
| ++                opt->posPrev = cur + lenTest + 1;
 | |
| ++                opt->backPrev = 0;
 | |
| ++                opt->prev1IsChar = True;
 | |
| ++                opt->prev2 = True;
 | |
| ++                opt->posPrev2 = cur;
 | |
| ++                opt->backPrev2 = curBack + LZMA_NUM_REPS;
 | |
| ++              }
 | |
| ++            }
 | |
| ++          }
 | |
| ++          offs += 2;
 | |
| ++          if (offs == numPairs)
 | |
| ++            break;
 | |
| ++          curBack = matches[offs + 1];
 | |
| ++          if (curBack >= kNumFullDistances)
 | |
| ++            GetPosSlot2(curBack, posSlot);
 | |
| ++        }
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++}
 | |
| ++
 | |
| ++#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
 | |
| ++
 | |
| ++static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
 | |
| ++{
 | |
| ++  UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
 | |
| ++  const Byte *data;
 | |
| ++  const UInt32 *matches;
 | |
| ++
 | |
| ++  if (p->additionalOffset == 0)
 | |
| ++    mainLen = ReadMatchDistances(p, &numPairs);
 | |
| ++  else
 | |
| ++  {
 | |
| ++    mainLen = p->longestMatchLength;
 | |
| ++    numPairs = p->numPairs;
 | |
| ++  }
 | |
| ++
 | |
| ++  numAvail = p->numAvail;
 | |
| ++  *backRes = (UInt32)-1;
 | |
| ++  if (numAvail < 2)
 | |
| ++    return 1;
 | |
| ++  if (numAvail > LZMA_MATCH_LEN_MAX)
 | |
| ++    numAvail = LZMA_MATCH_LEN_MAX;
 | |
| ++  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
 | |
| ++
 | |
| ++  repLen = repIndex = 0;
 | |
| ++  for (i = 0; i < LZMA_NUM_REPS; i++)
 | |
| ++  {
 | |
| ++    UInt32 len;
 | |
| ++    const Byte *data2 = data - (p->reps[i] + 1);
 | |
| ++    if (data[0] != data2[0] || data[1] != data2[1])
 | |
| ++      continue;
 | |
| ++    for (len = 2; len < numAvail && data[len] == data2[len]; len++);
 | |
| ++    if (len >= p->numFastBytes)
 | |
| ++    {
 | |
| ++      *backRes = i;
 | |
| ++      MovePos(p, len - 1);
 | |
| ++      return len;
 | |
| ++    }
 | |
| ++    if (len > repLen)
 | |
| ++    {
 | |
| ++      repIndex = i;
 | |
| ++      repLen = len;
 | |
| ++    }
 | |
| ++  }
 | |
| ++
 | |
| ++  matches = p->matches;
 | |
| ++  if (mainLen >= p->numFastBytes)
 | |
| ++  {
 | |
| ++    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
 | |
| ++    MovePos(p, mainLen - 1);
 | |
| ++    return mainLen;
 | |
| ++  }
 | |
| ++
 | |
| ++  mainDist = 0; /* for GCC */
 | |
| ++  if (mainLen >= 2)
 | |
| ++  {
 | |
| ++    mainDist = matches[numPairs - 1];
 | |
| ++    while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
 | |
| ++    {
 | |
| ++      if (!ChangePair(matches[numPairs - 3], mainDist))
 | |
| ++        break;
 | |
| ++      numPairs -= 2;
 | |
| ++      mainLen = matches[numPairs - 2];
 | |
| ++      mainDist = matches[numPairs - 1];
 | |
| ++    }
 | |
| ++    if (mainLen == 2 && mainDist >= 0x80)
 | |
| ++      mainLen = 1;
 | |
| ++  }
 | |
| ++
 | |
| ++  if (repLen >= 2 && (
 | |
| ++        (repLen + 1 >= mainLen) ||
 | |
| ++        (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
 | |
| ++        (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
 | |
| ++  {
 | |
| ++    *backRes = repIndex;
 | |
| ++    MovePos(p, repLen - 1);
 | |
| ++    return repLen;
 | |
| ++  }
 | |
| ++
 | |
| ++  if (mainLen < 2 || numAvail <= 2)
 | |
| ++    return 1;
 | |
| ++
 | |
| ++  p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
 | |
| ++  if (p->longestMatchLength >= 2)
 | |
| ++  {
 | |
| ++    UInt32 newDistance = matches[p->numPairs - 1];
 | |
| ++    if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
 | |
| ++        (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
 | |
| ++        (p->longestMatchLength > mainLen + 1) ||
 | |
| ++        (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
 | |
| ++      return 1;
 | |
| ++  }
 | |
| ++
 | |
| ++  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
 | |
| ++  for (i = 0; i < LZMA_NUM_REPS; i++)
 | |
| ++  {
 | |
| ++    UInt32 len, limit;
 | |
| ++    const Byte *data2 = data - (p->reps[i] + 1);
 | |
| ++    if (data[0] != data2[0] || data[1] != data2[1])
 | |
| ++      continue;
 | |
| ++    limit = mainLen - 1;
 | |
| ++    for (len = 2; len < limit && data[len] == data2[len]; len++);
 | |
| ++    if (len >= limit)
 | |
| ++      return 1;
 | |
| ++  }
 | |
| ++  *backRes = mainDist + LZMA_NUM_REPS;
 | |
| ++  MovePos(p, mainLen - 2);
 | |
| ++  return mainLen;
 | |
| ++}
 | |
| ++
 | |
| ++static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
 | |
| ++{
 | |
| ++  UInt32 len;
 | |
| ++  RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
 | |
| ++  RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
 | |
| ++  p->state = kMatchNextStates[p->state];
 | |
| ++  len = LZMA_MATCH_LEN_MIN;
 | |
| ++  LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
 | |
| ++  RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
 | |
| ++  RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
 | |
| ++  RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
 | |
| ++}
 | |
| ++
 | |
| ++static SRes CheckErrors(CLzmaEnc *p)
 | |
| ++{
 | |
| ++  if (p->result != SZ_OK)
 | |
| ++    return p->result;
 | |
| ++  if (p->rc.res != SZ_OK)
 | |
| ++    p->result = SZ_ERROR_WRITE;
 | |
| ++  if (p->matchFinderBase.result != SZ_OK)
 | |
| ++    p->result = SZ_ERROR_READ;
 | |
| ++  if (p->result != SZ_OK)
 | |
| ++    p->finished = True;
 | |
| ++  return p->result;
 | |
| ++}
 | |
| ++
 | |
| ++static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
 | |
| ++{
 | |
| ++  /* ReleaseMFStream(); */
 | |
| ++  p->finished = True;
 | |
| ++  if (p->writeEndMark)
 | |
| ++    WriteEndMarker(p, nowPos & p->pbMask);
 | |
| ++  RangeEnc_FlushData(&p->rc);
 | |
| ++  RangeEnc_FlushStream(&p->rc);
 | |
| ++  return CheckErrors(p);
 | |
| ++}
 | |
| ++
 | |
| ++static void FillAlignPrices(CLzmaEnc *p)
 | |
| ++{
 | |
| ++  UInt32 i;
 | |
| ++  for (i = 0; i < kAlignTableSize; i++)
 | |
| ++    p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
 | |
| ++  p->alignPriceCount = 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void FillDistancesPrices(CLzmaEnc *p)
 | |
| ++{
 | |
| ++  UInt32 tempPrices[kNumFullDistances];
 | |
| ++  UInt32 i, lenToPosState;
 | |
| ++  for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
 | |
| ++  {
 | |
| ++    UInt32 posSlot = GetPosSlot1(i);
 | |
| ++    UInt32 footerBits = ((posSlot >> 1) - 1);
 | |
| ++    UInt32 base = ((2 | (posSlot & 1)) << footerBits);
 | |
| ++    tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
 | |
| ++  }
 | |
| ++
 | |
| ++  for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
 | |
| ++  {
 | |
| ++    UInt32 posSlot;
 | |
| ++    const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
 | |
| ++    UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
 | |
| ++    for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
 | |
| ++      posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
 | |
| ++    for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
 | |
| ++      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
 | |
| ++
 | |
| ++    {
 | |
| ++      UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
 | |
| ++      UInt32 i;
 | |
| ++      for (i = 0; i < kStartPosModelIndex; i++)
 | |
| ++        distancesPrices[i] = posSlotPrices[i];
 | |
| ++      for (; i < kNumFullDistances; i++)
 | |
| ++        distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
 | |
| ++    }
 | |
| ++  }
 | |
| ++  p->matchPriceCount = 0;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_Construct(CLzmaEnc *p)
 | |
| ++{
 | |
| ++  RangeEnc_Construct(&p->rc);
 | |
| ++  MatchFinder_Construct(&p->matchFinderBase);
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  MatchFinderMt_Construct(&p->matchFinderMt);
 | |
| ++  p->matchFinderMt.MatchFinder = &p->matchFinderBase;
 | |
| ++  #endif
 | |
| ++
 | |
| ++  {
 | |
| ++    CLzmaEncProps props;
 | |
| ++    LzmaEncProps_Init(&props);
 | |
| ++    LzmaEnc_SetProps(p, &props);
 | |
| ++  }
 | |
| ++
 | |
| ++  #ifndef LZMA_LOG_BSR
 | |
| ++  LzmaEnc_FastPosInit(p->g_FastPos);
 | |
| ++  #endif
 | |
| ++
 | |
| ++  LzmaEnc_InitPriceTables(p->ProbPrices);
 | |
| ++  p->litProbs = 0;
 | |
| ++  p->saveState.litProbs = 0;
 | |
| ++}
 | |
| ++
 | |
| ++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  void *p;
 | |
| ++  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
 | |
| ++  if (p != 0)
 | |
| ++    LzmaEnc_Construct((CLzmaEnc *)p);
 | |
| ++  return p;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
 | |
| ++{
 | |
| ++  alloc->Free(alloc, p->litProbs);
 | |
| ++  alloc->Free(alloc, p->saveState.litProbs);
 | |
| ++  p->litProbs = 0;
 | |
| ++  p->saveState.litProbs = 0;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
 | |
| ++  #endif
 | |
| ++  MatchFinder_Free(&p->matchFinderBase, allocBig);
 | |
| ++  LzmaEnc_FreeLits(p, alloc);
 | |
| ++  RangeEnc_Free(&p->rc, alloc);
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
 | |
| ++  alloc->Free(alloc, p);
 | |
| ++}
 | |
| ++
 | |
| ++static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
 | |
| ++{
 | |
| ++  UInt32 nowPos32, startPos32;
 | |
| ++  if (p->needInit)
 | |
| ++  {
 | |
| ++    p->matchFinder.Init(p->matchFinderObj);
 | |
| ++    p->needInit = 0;
 | |
| ++  }
 | |
| ++
 | |
| ++  if (p->finished)
 | |
| ++    return p->result;
 | |
| ++  RINOK(CheckErrors(p));
 | |
| ++
 | |
| ++  nowPos32 = (UInt32)p->nowPos64;
 | |
| ++  startPos32 = nowPos32;
 | |
| ++
 | |
| ++  if (p->nowPos64 == 0)
 | |
| ++  {
 | |
| ++    UInt32 numPairs;
 | |
| ++    Byte curByte;
 | |
| ++    if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
 | |
| ++      return Flush(p, nowPos32);
 | |
| ++    ReadMatchDistances(p, &numPairs);
 | |
| ++    RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
 | |
| ++    p->state = kLiteralNextStates[p->state];
 | |
| ++    curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
 | |
| ++    LitEnc_Encode(&p->rc, p->litProbs, curByte);
 | |
| ++    p->additionalOffset--;
 | |
| ++    nowPos32++;
 | |
| ++  }
 | |
| ++
 | |
| ++  if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    UInt32 pos, len, posState;
 | |
| ++
 | |
| ++    if (p->fastMode)
 | |
| ++      len = GetOptimumFast(p, &pos);
 | |
| ++    else
 | |
| ++      len = GetOptimum(p, nowPos32, &pos);
 | |
| ++
 | |
| ++    #ifdef SHOW_STAT2
 | |
| ++    printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos);
 | |
| ++    #endif
 | |
| ++
 | |
| ++    posState = nowPos32 & p->pbMask;
 | |
| ++    if (len == 1 && pos == (UInt32)-1)
 | |
| ++    {
 | |
| ++      Byte curByte;
 | |
| ++      CLzmaProb *probs;
 | |
| ++      const Byte *data;
 | |
| ++
 | |
| ++      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
 | |
| ++      data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
 | |
| ++      curByte = *data;
 | |
| ++      probs = LIT_PROBS(nowPos32, *(data - 1));
 | |
| ++      if (IsCharState(p->state))
 | |
| ++        LitEnc_Encode(&p->rc, probs, curByte);
 | |
| ++      else
 | |
| ++        LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
 | |
| ++      p->state = kLiteralNextStates[p->state];
 | |
| ++    }
 | |
| ++    else
 | |
| ++    {
 | |
| ++      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
 | |
| ++      if (pos < LZMA_NUM_REPS)
 | |
| ++      {
 | |
| ++        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
 | |
| ++        if (pos == 0)
 | |
| ++        {
 | |
| ++          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
 | |
| ++          RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
 | |
| ++        }
 | |
| ++        else
 | |
| ++        {
 | |
| ++          UInt32 distance = p->reps[pos];
 | |
| ++          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
 | |
| ++          if (pos == 1)
 | |
| ++            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
 | |
| ++          else
 | |
| ++          {
 | |
| ++            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
 | |
| ++            RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
 | |
| ++            if (pos == 3)
 | |
| ++              p->reps[3] = p->reps[2];
 | |
| ++            p->reps[2] = p->reps[1];
 | |
| ++          }
 | |
| ++          p->reps[1] = p->reps[0];
 | |
| ++          p->reps[0] = distance;
 | |
| ++        }
 | |
| ++        if (len == 1)
 | |
| ++          p->state = kShortRepNextStates[p->state];
 | |
| ++        else
 | |
| ++        {
 | |
| ++          LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
 | |
| ++          p->state = kRepNextStates[p->state];
 | |
| ++        }
 | |
| ++      }
 | |
| ++      else
 | |
| ++      {
 | |
| ++        UInt32 posSlot;
 | |
| ++        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
 | |
| ++        p->state = kMatchNextStates[p->state];
 | |
| ++        LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
 | |
| ++        pos -= LZMA_NUM_REPS;
 | |
| ++        GetPosSlot(pos, posSlot);
 | |
| ++        RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
 | |
| ++
 | |
| ++        if (posSlot >= kStartPosModelIndex)
 | |
| ++        {
 | |
| ++          UInt32 footerBits = ((posSlot >> 1) - 1);
 | |
| ++          UInt32 base = ((2 | (posSlot & 1)) << footerBits);
 | |
| ++          UInt32 posReduced = pos - base;
 | |
| ++
 | |
| ++          if (posSlot < kEndPosModelIndex)
 | |
| ++            RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
 | |
| ++          else
 | |
| ++          {
 | |
| ++            RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
 | |
| ++            RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
 | |
| ++            p->alignPriceCount++;
 | |
| ++          }
 | |
| ++        }
 | |
| ++        p->reps[3] = p->reps[2];
 | |
| ++        p->reps[2] = p->reps[1];
 | |
| ++        p->reps[1] = p->reps[0];
 | |
| ++        p->reps[0] = pos;
 | |
| ++        p->matchPriceCount++;
 | |
| ++      }
 | |
| ++    }
 | |
| ++    p->additionalOffset -= len;
 | |
| ++    nowPos32 += len;
 | |
| ++    if (p->additionalOffset == 0)
 | |
| ++    {
 | |
| ++      UInt32 processed;
 | |
| ++      if (!p->fastMode)
 | |
| ++      {
 | |
| ++        if (p->matchPriceCount >= (1 << 7))
 | |
| ++          FillDistancesPrices(p);
 | |
| ++        if (p->alignPriceCount >= kAlignTableSize)
 | |
| ++          FillAlignPrices(p);
 | |
| ++      }
 | |
| ++      if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
 | |
| ++        break;
 | |
| ++      processed = nowPos32 - startPos32;
 | |
| ++      if (useLimits)
 | |
| ++      {
 | |
| ++        if (processed + kNumOpts + 300 >= maxUnpackSize ||
 | |
| ++            RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
 | |
| ++          break;
 | |
| ++      }
 | |
| ++      else if (processed >= (1 << 15))
 | |
| ++      {
 | |
| ++        p->nowPos64 += nowPos32 - startPos32;
 | |
| ++        return CheckErrors(p);
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++  p->nowPos64 += nowPos32 - startPos32;
 | |
| ++  return Flush(p, nowPos32);
 | |
| ++}
 | |
| ++
 | |
| ++#define kBigHashDicLimit ((UInt32)1 << 24)
 | |
| ++
 | |
| ++static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  UInt32 beforeSize = kNumOpts;
 | |
| ++  Bool btMode;
 | |
| ++  if (!RangeEnc_Alloc(&p->rc, alloc))
 | |
| ++    return SZ_ERROR_MEM;
 | |
| ++  btMode = (p->matchFinderBase.btMode != 0);
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  p->mtMode = (p->multiThread && !p->fastMode && btMode);
 | |
| ++  #endif
 | |
| ++
 | |
| ++  {
 | |
| ++    unsigned lclp = p->lc + p->lp;
 | |
| ++    if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
 | |
| ++    {
 | |
| ++      LzmaEnc_FreeLits(p, alloc);
 | |
| ++      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
 | |
| ++      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
 | |
| ++      if (p->litProbs == 0 || p->saveState.litProbs == 0)
 | |
| ++      {
 | |
| ++        LzmaEnc_FreeLits(p, alloc);
 | |
| ++        return SZ_ERROR_MEM;
 | |
| ++      }
 | |
| ++      p->lclp = lclp;
 | |
| ++    }
 | |
| ++  }
 | |
| ++
 | |
| ++  p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
 | |
| ++
 | |
| ++  if (beforeSize + p->dictSize < keepWindowSize)
 | |
| ++    beforeSize = keepWindowSize - p->dictSize;
 | |
| ++
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  if (p->mtMode)
 | |
| ++  {
 | |
| ++    RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
 | |
| ++    p->matchFinderObj = &p->matchFinderMt;
 | |
| ++    MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
 | |
| ++  }
 | |
| ++  else
 | |
| ++  #endif
 | |
| ++  {
 | |
| ++    if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
 | |
| ++      return SZ_ERROR_MEM;
 | |
| ++    p->matchFinderObj = &p->matchFinderBase;
 | |
| ++    MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
 | |
| ++  }
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_Init(CLzmaEnc *p)
 | |
| ++{
 | |
| ++  UInt32 i;
 | |
| ++  p->state = 0;
 | |
| ++  for (i = 0 ; i < LZMA_NUM_REPS; i++)
 | |
| ++    p->reps[i] = 0;
 | |
| ++
 | |
| ++  RangeEnc_Init(&p->rc);
 | |
| ++
 | |
| ++
 | |
| ++  for (i = 0; i < kNumStates; i++)
 | |
| ++  {
 | |
| ++    UInt32 j;
 | |
| ++    for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
 | |
| ++    {
 | |
| ++      p->isMatch[i][j] = kProbInitValue;
 | |
| ++      p->isRep0Long[i][j] = kProbInitValue;
 | |
| ++    }
 | |
| ++    p->isRep[i] = kProbInitValue;
 | |
| ++    p->isRepG0[i] = kProbInitValue;
 | |
| ++    p->isRepG1[i] = kProbInitValue;
 | |
| ++    p->isRepG2[i] = kProbInitValue;
 | |
| ++  }
 | |
| ++
 | |
| ++  {
 | |
| ++    UInt32 num = 0x300 << (p->lp + p->lc);
 | |
| ++    for (i = 0; i < num; i++)
 | |
| ++      p->litProbs[i] = kProbInitValue;
 | |
| ++  }
 | |
| ++
 | |
| ++  {
 | |
| ++    for (i = 0; i < kNumLenToPosStates; i++)
 | |
| ++    {
 | |
| ++      CLzmaProb *probs = p->posSlotEncoder[i];
 | |
| ++      UInt32 j;
 | |
| ++      for (j = 0; j < (1 << kNumPosSlotBits); j++)
 | |
| ++        probs[j] = kProbInitValue;
 | |
| ++    }
 | |
| ++  }
 | |
| ++  {
 | |
| ++    for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
 | |
| ++      p->posEncoders[i] = kProbInitValue;
 | |
| ++  }
 | |
| ++
 | |
| ++  LenEnc_Init(&p->lenEnc.p);
 | |
| ++  LenEnc_Init(&p->repLenEnc.p);
 | |
| ++
 | |
| ++  for (i = 0; i < (1 << kNumAlignBits); i++)
 | |
| ++    p->posAlignEncoder[i] = kProbInitValue;
 | |
| ++
 | |
| ++  p->optimumEndIndex = 0;
 | |
| ++  p->optimumCurrentIndex = 0;
 | |
| ++  p->additionalOffset = 0;
 | |
| ++
 | |
| ++  p->pbMask = (1 << p->pb) - 1;
 | |
| ++  p->lpMask = (1 << p->lp) - 1;
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_InitPrices(CLzmaEnc *p)
 | |
| ++{
 | |
| ++  if (!p->fastMode)
 | |
| ++  {
 | |
| ++    FillDistancesPrices(p);
 | |
| ++    FillAlignPrices(p);
 | |
| ++  }
 | |
| ++
 | |
| ++  p->lenEnc.tableSize =
 | |
| ++  p->repLenEnc.tableSize =
 | |
| ++      p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
 | |
| ++  LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
 | |
| ++  LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
 | |
| ++}
 | |
| ++
 | |
| ++static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  UInt32 i;
 | |
| ++  for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
 | |
| ++    if (p->dictSize <= ((UInt32)1 << i))
 | |
| ++      break;
 | |
| ++  p->distTableSize = i * 2;
 | |
| ++
 | |
| ++  p->finished = False;
 | |
| ++  p->result = SZ_OK;
 | |
| ++  RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
 | |
| ++  LzmaEnc_Init(p);
 | |
| ++  LzmaEnc_InitPrices(p);
 | |
| ++  p->nowPos64 = 0;
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
 | |
| ++    ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  p->matchFinderBase.stream = inStream;
 | |
| ++  p->needInit = 1;
 | |
| ++  p->rc.outStream = outStream;
 | |
| ++  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
 | |
| ++    ISeqInStream *inStream, UInt32 keepWindowSize,
 | |
| ++    ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  p->matchFinderBase.stream = inStream;
 | |
| ++  p->needInit = 1;
 | |
| ++  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
 | |
| ++}
 | |
| ++
 | |
| ++static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
 | |
| ++{
 | |
| ++  p->matchFinderBase.directInput = 1;
 | |
| ++  p->matchFinderBase.bufferBase = (Byte *)src;
 | |
| ++  p->matchFinderBase.directInputRem = srcLen;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
 | |
| ++    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  LzmaEnc_SetInputBuf(p, src, srcLen);
 | |
| ++  p->needInit = 1;
 | |
| ++
 | |
| ++  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
 | |
| ++}
 | |
| ++
 | |
| ++void LzmaEnc_Finish(CLzmaEncHandle pp)
 | |
| ++{
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  if (p->mtMode)
 | |
| ++    MatchFinderMt_ReleaseStream(&p->matchFinderMt);
 | |
| ++  #else
 | |
| ++  pp = pp;
 | |
| ++  #endif
 | |
| ++}
 | |
| ++
 | |
| ++typedef struct
 | |
| ++{
 | |
| ++  ISeqOutStream funcTable;
 | |
| ++  Byte *data;
 | |
| ++  SizeT rem;
 | |
| ++  Bool overflow;
 | |
| ++} CSeqOutStreamBuf;
 | |
| ++
 | |
| ++static size_t MyWrite(void *pp, const void *data, size_t size)
 | |
| ++{
 | |
| ++  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
 | |
| ++  if (p->rem < size)
 | |
| ++  {
 | |
| ++    size = p->rem;
 | |
| ++    p->overflow = True;
 | |
| ++  }
 | |
| ++  memcpy(p->data, data, size);
 | |
| ++  p->rem -= size;
 | |
| ++  p->data += size;
 | |
| ++  return size;
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
 | |
| ++{
 | |
| ++  const CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
 | |
| ++}
 | |
| ++
 | |
| ++const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
 | |
| ++{
 | |
| ++  const CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
 | |
| ++    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  UInt64 nowPos64;
 | |
| ++  SRes res;
 | |
| ++  CSeqOutStreamBuf outStream;
 | |
| ++
 | |
| ++  outStream.funcTable.Write = MyWrite;
 | |
| ++  outStream.data = dest;
 | |
| ++  outStream.rem = *destLen;
 | |
| ++  outStream.overflow = False;
 | |
| ++
 | |
| ++  p->writeEndMark = False;
 | |
| ++  p->finished = False;
 | |
| ++  p->result = SZ_OK;
 | |
| ++
 | |
| ++  if (reInit)
 | |
| ++    LzmaEnc_Init(p);
 | |
| ++  LzmaEnc_InitPrices(p);
 | |
| ++  nowPos64 = p->nowPos64;
 | |
| ++  RangeEnc_Init(&p->rc);
 | |
| ++  p->rc.outStream = &outStream.funcTable;
 | |
| ++
 | |
| ++  res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
 | |
| ++
 | |
| ++  *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
 | |
| ++  *destLen -= outStream.rem;
 | |
| ++  if (outStream.overflow)
 | |
| ++    return SZ_ERROR_OUTPUT_EOF;
 | |
| ++
 | |
| ++  return res;
 | |
| ++}
 | |
| ++
 | |
| ++static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
 | |
| ++{
 | |
| ++  SRes res = SZ_OK;
 | |
| ++
 | |
| ++  #ifndef _7ZIP_ST
 | |
| ++  Byte allocaDummy[0x300];
 | |
| ++  int i = 0;
 | |
| ++  for (i = 0; i < 16; i++)
 | |
| ++    allocaDummy[i] = (Byte)i;
 | |
| ++  #endif
 | |
| ++
 | |
| ++  for (;;)
 | |
| ++  {
 | |
| ++    res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
 | |
| ++    if (res != SZ_OK || p->finished != 0)
 | |
| ++      break;
 | |
| ++    if (progress != 0)
 | |
| ++    {
 | |
| ++      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
 | |
| ++      if (res != SZ_OK)
 | |
| ++      {
 | |
| ++        res = SZ_ERROR_PROGRESS;
 | |
| ++        break;
 | |
| ++      }
 | |
| ++    }
 | |
| ++  }
 | |
| ++  LzmaEnc_Finish(p);
 | |
| ++  return res;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
 | |
| ++    ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
 | |
| ++  return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++  int i;
 | |
| ++  UInt32 dictSize = p->dictSize;
 | |
| ++  if (*size < LZMA_PROPS_SIZE)
 | |
| ++    return SZ_ERROR_PARAM;
 | |
| ++  *size = LZMA_PROPS_SIZE;
 | |
| ++  props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
 | |
| ++
 | |
| ++  for (i = 11; i <= 30; i++)
 | |
| ++  {
 | |
| ++    if (dictSize <= ((UInt32)2 << i))
 | |
| ++    {
 | |
| ++      dictSize = (2 << i);
 | |
| ++      break;
 | |
| ++    }
 | |
| ++    if (dictSize <= ((UInt32)3 << i))
 | |
| ++    {
 | |
| ++      dictSize = (3 << i);
 | |
| ++      break;
 | |
| ++    }
 | |
| ++  }
 | |
| ++
 | |
| ++  for (i = 0; i < 4; i++)
 | |
| ++    props[1 + i] = (Byte)(dictSize >> (8 * i));
 | |
| ++  return SZ_OK;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
 | |
| ++    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  SRes res;
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)pp;
 | |
| ++
 | |
| ++  CSeqOutStreamBuf outStream;
 | |
| ++
 | |
| ++  LzmaEnc_SetInputBuf(p, src, srcLen);
 | |
| ++
 | |
| ++  outStream.funcTable.Write = MyWrite;
 | |
| ++  outStream.data = dest;
 | |
| ++  outStream.rem = *destLen;
 | |
| ++  outStream.overflow = False;
 | |
| ++
 | |
| ++  p->writeEndMark = writeEndMark;
 | |
| ++
 | |
| ++  p->rc.outStream = &outStream.funcTable;
 | |
| ++  res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
 | |
| ++  if (res == SZ_OK)
 | |
| ++    res = LzmaEnc_Encode2(p, progress);
 | |
| ++
 | |
| ++  *destLen -= outStream.rem;
 | |
| ++  if (outStream.overflow)
 | |
| ++    return SZ_ERROR_OUTPUT_EOF;
 | |
| ++  return res;
 | |
| ++}
 | |
| ++
 | |
| ++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
 | |
| ++    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
 | |
| ++    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
 | |
| ++{
 | |
| ++  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
 | |
| ++  SRes res;
 | |
| ++  if (p == 0)
 | |
| ++    return SZ_ERROR_MEM;
 | |
| ++
 | |
| ++  res = LzmaEnc_SetProps(p, props);
 | |
| ++  if (res == SZ_OK)
 | |
| ++  {
 | |
| ++    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
 | |
| ++    if (res == SZ_OK)
 | |
| ++      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
 | |
| ++          writeEndMark, progress, alloc, allocBig);
 | |
| ++  }
 | |
| ++
 | |
| ++  LzmaEnc_Destroy(p, alloc, allocBig);
 | |
| ++  return res;
 | |
| ++}
 | |
| +--- /dev/null
 | |
| ++++ b/lib/lzma/Makefile
 | |
| +@@ -0,0 +1,7 @@
 | |
| ++lzma_compress-objs := LzFind.o LzmaEnc.o
 | |
| ++lzma_decompress-objs := LzmaDec.o
 | |
| ++
 | |
| ++obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o
 | |
| ++obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o
 | |
| ++
 | |
| ++EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h
 | |
| diff --git a/target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch b/target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a1d7dc1a69
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/532-jffs2_eofdetect.patch
 | |
| @@ -0,0 +1,65 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: fs: jffs2: EOF marker
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + fs/jffs2/build.c | 10 ++++++++++
 | |
| + fs/jffs2/scan.c  | 21 +++++++++++++++++++--
 | |
| + 2 files changed, 29 insertions(+), 2 deletions(-)
 | |
| +
 | |
| +--- a/fs/jffs2/build.c
 | |
| ++++ b/fs/jffs2/build.c
 | |
| +@@ -117,6 +117,16 @@ static int jffs2_build_filesystem(struct
 | |
| + 	dbg_fsbuild("scanned flash completely\n");
 | |
| + 	jffs2_dbg_dump_block_lists_nolock(c);
 | |
| + 
 | |
| ++	if (c->flags & (1 << 7)) {
 | |
| ++		printk("%s(): unlocking the mtd device... ", __func__);
 | |
| ++		mtd_unlock(c->mtd, 0, c->mtd->size);
 | |
| ++		printk("done.\n");
 | |
| ++
 | |
| ++		printk("%s(): erasing all blocks after the end marker... ", __func__);
 | |
| ++		jffs2_erase_pending_blocks(c, -1);
 | |
| ++		printk("done.\n");
 | |
| ++	}
 | |
| ++
 | |
| + 	dbg_fsbuild("pass 1 starting\n");
 | |
| + 	c->flags |= JFFS2_SB_FLAG_BUILDING;
 | |
| + 	/* Now scan the directory tree, increasing nlink according to every dirent found. */
 | |
| +--- a/fs/jffs2/scan.c
 | |
| ++++ b/fs/jffs2/scan.c
 | |
| +@@ -148,8 +148,14 @@ int jffs2_scan_medium(struct jffs2_sb_in
 | |
| + 		/* reset summary info for next eraseblock scan */
 | |
| + 		jffs2_sum_reset_collected(s);
 | |
| + 
 | |
| +-		ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
 | |
| +-						buf_size, s);
 | |
| ++		if (c->flags & (1 << 7)) {
 | |
| ++			if (mtd_block_isbad(c->mtd, jeb->offset))
 | |
| ++				ret = BLK_STATE_BADBLOCK;
 | |
| ++			else
 | |
| ++				ret = BLK_STATE_ALLFF;
 | |
| ++		} else
 | |
| ++			ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
 | |
| ++							buf_size, s);
 | |
| + 
 | |
| + 		if (ret < 0)
 | |
| + 			goto out;
 | |
| +@@ -565,6 +571,17 @@ full_scan:
 | |
| + 			return err;
 | |
| + 	}
 | |
| + 
 | |
| ++	if ((buf[0] == 0xde) &&
 | |
| ++		(buf[1] == 0xad) &&
 | |
| ++		(buf[2] == 0xc0) &&
 | |
| ++		(buf[3] == 0xde)) {
 | |
| ++		/* end of filesystem. erase everything after this point */
 | |
| ++		printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
 | |
| ++		c->flags |= (1 << 7);
 | |
| ++
 | |
| ++		return BLK_STATE_ALLFF;
 | |
| ++	}
 | |
| ++
 | |
| + 	/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
 | |
| + 	ofs = 0;
 | |
| + 	max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
 | |
| diff --git a/target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch b/target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch
 | |
| new file mode 100644
 | |
| index 0000000000..f82849c356
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/600-netfilter_conntrack_flush.patch
 | |
| @@ -0,0 +1,88 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: netfilter: add support for flushing conntrack via /proc
 | |
| +
 | |
| +lede-commit 8193bbe59a74d34d6a26d4a8cb857b1952905314
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + net/netfilter/nf_conntrack_standalone.c | 59 ++++++++++++++++++++++++++++++++-
 | |
| + 1 file changed, 58 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/net/netfilter/nf_conntrack_standalone.c
 | |
| ++++ b/net/netfilter/nf_conntrack_standalone.c
 | |
| +@@ -9,6 +9,7 @@
 | |
| + #include <linux/percpu.h>
 | |
| + #include <linux/netdevice.h>
 | |
| + #include <linux/security.h>
 | |
| ++#include <linux/inet.h>
 | |
| + #include <net/net_namespace.h>
 | |
| + #ifdef CONFIG_SYSCTL
 | |
| + #include <linux/sysctl.h>
 | |
| +@@ -456,6 +457,56 @@ static int ct_cpu_seq_show(struct seq_fi
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| ++struct kill_request {
 | |
| ++	u16 family;
 | |
| ++	union nf_inet_addr addr;
 | |
| ++};
 | |
| ++
 | |
| ++static int kill_matching(struct nf_conn *i, void *data)
 | |
| ++{
 | |
| ++	struct kill_request *kr = data;
 | |
| ++	struct nf_conntrack_tuple *t1 = &i->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
 | |
| ++	struct nf_conntrack_tuple *t2 = &i->tuplehash[IP_CT_DIR_REPLY].tuple;
 | |
| ++
 | |
| ++	if (!kr->family)
 | |
| ++		return 1;
 | |
| ++
 | |
| ++	if (t1->src.l3num != kr->family)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	return (nf_inet_addr_cmp(&kr->addr, &t1->src.u3) ||
 | |
| ++	        nf_inet_addr_cmp(&kr->addr, &t1->dst.u3) ||
 | |
| ++	        nf_inet_addr_cmp(&kr->addr, &t2->src.u3) ||
 | |
| ++	        nf_inet_addr_cmp(&kr->addr, &t2->dst.u3));
 | |
| ++}
 | |
| ++
 | |
| ++static int ct_file_write(struct file *file, char *buf, size_t count)
 | |
| ++{
 | |
| ++	struct seq_file *seq = file->private_data;
 | |
| ++	struct net *net = seq_file_net(seq);
 | |
| ++	struct kill_request kr = { };
 | |
| ++
 | |
| ++	if (count == 0)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	if (count >= INET6_ADDRSTRLEN)
 | |
| ++		count = INET6_ADDRSTRLEN - 1;
 | |
| ++
 | |
| ++	if (strnchr(buf, count, ':')) {
 | |
| ++		kr.family = AF_INET6;
 | |
| ++		if (!in6_pton(buf, count, (void *)&kr.addr, '\n', NULL))
 | |
| ++			return -EINVAL;
 | |
| ++	} else if (strnchr(buf, count, '.')) {
 | |
| ++		kr.family = AF_INET;
 | |
| ++		if (!in4_pton(buf, count, (void *)&kr.addr, '\n', NULL))
 | |
| ++			return -EINVAL;
 | |
| ++	}
 | |
| ++
 | |
| ++	nf_ct_iterate_cleanup_net(net, kill_matching, &kr, 0, 0);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static const struct seq_operations ct_cpu_seq_ops = {
 | |
| + 	.start	= ct_cpu_seq_start,
 | |
| + 	.next	= ct_cpu_seq_next,
 | |
| +@@ -469,8 +520,9 @@ static int nf_conntrack_standalone_init_
 | |
| + 	kuid_t root_uid;
 | |
| + 	kgid_t root_gid;
 | |
| + 
 | |
| +-	pde = proc_create_net("nf_conntrack", 0440, net->proc_net, &ct_seq_ops,
 | |
| +-			sizeof(struct ct_iter_state));
 | |
| ++	pde = proc_create_net_data_write("nf_conntrack", 0440, net->proc_net,
 | |
| ++					 &ct_seq_ops, &ct_file_write,
 | |
| ++					 sizeof(struct ct_iter_state), NULL);
 | |
| + 	if (!pde)
 | |
| + 		goto out_nf_conntrack;
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch b/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch
 | |
| new file mode 100644
 | |
| index 0000000000..457703121c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/610-netfilter_match_bypass_default_checks.patch
 | |
| @@ -0,0 +1,110 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: kernel: add a new version of my netfilter speedup patches for linux 2.6.39 and 3.0
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/uapi/linux/netfilter_ipv4/ip_tables.h |  1 +
 | |
| + net/ipv4/netfilter/ip_tables.c                | 37 +++++++++++++++++++++++++++
 | |
| + 2 files changed, 38 insertions(+)
 | |
| +
 | |
| +--- a/include/uapi/linux/netfilter_ipv4/ip_tables.h
 | |
| ++++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
 | |
| +@@ -89,6 +89,7 @@ struct ipt_ip {
 | |
| + #define IPT_F_FRAG		0x01	/* Set if rule is a fragment rule */
 | |
| + #define IPT_F_GOTO		0x02	/* Set if jump is a goto */
 | |
| + #define IPT_F_MASK		0x03	/* All possible flag bits mask. */
 | |
| ++#define IPT_F_NO_DEF_MATCH	0x80	/* Internal: no default match rules present */
 | |
| + 
 | |
| + /* Values for "inv" field in struct ipt_ip. */
 | |
| + #define IPT_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
 | |
| +--- a/net/ipv4/netfilter/ip_tables.c
 | |
| ++++ b/net/ipv4/netfilter/ip_tables.c
 | |
| +@@ -50,6 +50,9 @@ ip_packet_match(const struct iphdr *ip,
 | |
| + {
 | |
| + 	unsigned long ret;
 | |
| + 
 | |
| ++	if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
 | |
| ++		return true;
 | |
| ++
 | |
| + 	if (NF_INVF(ipinfo, IPT_INV_SRCIP,
 | |
| + 		    (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
 | |
| + 	    NF_INVF(ipinfo, IPT_INV_DSTIP,
 | |
| +@@ -80,6 +83,29 @@ ip_packet_match(const struct iphdr *ip,
 | |
| + 	return true;
 | |
| + }
 | |
| + 
 | |
| ++static void
 | |
| ++ip_checkdefault(struct ipt_ip *ip)
 | |
| ++{
 | |
| ++	static const char iface_mask[IFNAMSIZ] = {};
 | |
| ++
 | |
| ++	if (ip->invflags || ip->flags & IPT_F_FRAG)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (ip->smsk.s_addr || ip->dmsk.s_addr)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (ip->proto)
 | |
| ++		return;
 | |
| ++
 | |
| ++	ip->flags |= IPT_F_NO_DEF_MATCH;
 | |
| ++}
 | |
| ++
 | |
| + static bool
 | |
| + ip_checkentry(const struct ipt_ip *ip)
 | |
| + {
 | |
| +@@ -524,6 +550,8 @@ find_check_entry(struct ipt_entry *e, st
 | |
| + 	struct xt_mtchk_param mtpar;
 | |
| + 	struct xt_entry_match *ematch;
 | |
| + 
 | |
| ++	ip_checkdefault(&e->ip);
 | |
| ++
 | |
| + 	if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
 | |
| + 		return -ENOMEM;
 | |
| + 
 | |
| +@@ -818,6 +846,7 @@ copy_entries_to_user(unsigned int total_
 | |
| + 	const struct xt_table_info *private = table->private;
 | |
| + 	int ret = 0;
 | |
| + 	const void *loc_cpu_entry;
 | |
| ++	u8 flags;
 | |
| + 
 | |
| + 	counters = alloc_counters(table);
 | |
| + 	if (IS_ERR(counters))
 | |
| +@@ -845,6 +874,14 @@ copy_entries_to_user(unsigned int total_
 | |
| + 			goto free_counters;
 | |
| + 		}
 | |
| + 
 | |
| ++		flags = e->ip.flags & IPT_F_MASK;
 | |
| ++		if (copy_to_user(userptr + off
 | |
| ++				 + offsetof(struct ipt_entry, ip.flags),
 | |
| ++				 &flags, sizeof(flags)) != 0) {
 | |
| ++			ret = -EFAULT;
 | |
| ++			goto free_counters;
 | |
| ++		}
 | |
| ++
 | |
| + 		for (i = sizeof(struct ipt_entry);
 | |
| + 		     i < e->target_offset;
 | |
| + 		     i += m->u.match_size) {
 | |
| +@@ -1223,12 +1260,15 @@ compat_copy_entry_to_user(struct ipt_ent
 | |
| + 	compat_uint_t origsize;
 | |
| + 	const struct xt_entry_match *ematch;
 | |
| + 	int ret = 0;
 | |
| ++	u8 flags = e->ip.flags & IPT_F_MASK;
 | |
| + 
 | |
| + 	origsize = *size;
 | |
| + 	ce = *dstptr;
 | |
| + 	if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
 | |
| + 	    copy_to_user(&ce->counters, &counters[i],
 | |
| +-	    sizeof(counters[i])) != 0)
 | |
| ++	    sizeof(counters[i])) != 0 ||
 | |
| ++	    copy_to_user(&ce->ip.flags, &flags,
 | |
| ++	    sizeof(flags)) != 0)
 | |
| + 		return -EFAULT;
 | |
| + 
 | |
| + 	*dstptr += sizeof(struct compat_ipt_entry);
 | |
| diff --git a/target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch
 | |
| new file mode 100644
 | |
| index 0000000000..baf738a8d2
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/611-netfilter_match_bypass_default_table.patch
 | |
| @@ -0,0 +1,106 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: netfilter: match bypass default table
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + net/ipv4/netfilter/ip_tables.c | 79 +++++++++++++++++++++++++++++++-----------
 | |
| + 1 file changed, 58 insertions(+), 21 deletions(-)
 | |
| +
 | |
| +--- a/net/ipv4/netfilter/ip_tables.c
 | |
| ++++ b/net/ipv4/netfilter/ip_tables.c
 | |
| +@@ -246,6 +246,33 @@ struct ipt_entry *ipt_next_entry(const s
 | |
| + 	return (void *)entry + entry->next_offset;
 | |
| + }
 | |
| + 
 | |
| ++static bool
 | |
| ++ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
 | |
| ++{
 | |
| ++	struct xt_entry_target *t;
 | |
| ++	struct xt_standard_target *st;
 | |
| ++
 | |
| ++	if (e->target_offset != sizeof(struct ipt_entry))
 | |
| ++		return false;
 | |
| ++
 | |
| ++	if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
 | |
| ++		return false;
 | |
| ++
 | |
| ++	t = ipt_get_target(e);
 | |
| ++	if (t->u.kernel.target->target)
 | |
| ++		return false;
 | |
| ++
 | |
| ++	st = (struct xt_standard_target *) t;
 | |
| ++	if (st->verdict == XT_RETURN)
 | |
| ++		return false;
 | |
| ++
 | |
| ++	if (st->verdict >= 0)
 | |
| ++		return false;
 | |
| ++
 | |
| ++	*verdict = (unsigned)(-st->verdict) - 1;
 | |
| ++	return true;
 | |
| ++}
 | |
| ++
 | |
| + /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 | |
| + unsigned int
 | |
| + ipt_do_table(struct sk_buff *skb,
 | |
| +@@ -266,27 +293,28 @@ ipt_do_table(struct sk_buff *skb,
 | |
| + 	unsigned int addend;
 | |
| + 
 | |
| + 	/* Initialization */
 | |
| ++	WARN_ON(!(table->valid_hooks & (1 << hook)));
 | |
| ++	local_bh_disable();
 | |
| ++	private = READ_ONCE(table->private); /* Address dependency. */
 | |
| ++	cpu        = smp_processor_id();
 | |
| ++	table_base = private->entries;
 | |
| ++
 | |
| ++	e = get_entry(table_base, private->hook_entry[hook]);
 | |
| ++	if (ipt_handle_default_rule(e, &verdict)) {
 | |
| ++		struct xt_counters *counter;
 | |
| ++
 | |
| ++		counter = xt_get_this_cpu_counter(&e->counters);
 | |
| ++		ADD_COUNTER(*counter, skb->len, 1);
 | |
| ++		local_bh_enable();
 | |
| ++		return verdict;
 | |
| ++	}
 | |
| ++
 | |
| + 	stackidx = 0;
 | |
| + 	ip = ip_hdr(skb);
 | |
| + 	indev = state->in ? state->in->name : nulldevname;
 | |
| + 	outdev = state->out ? state->out->name : nulldevname;
 | |
| +-	/* We handle fragments by dealing with the first fragment as
 | |
| +-	 * if it was a normal packet.  All other fragments are treated
 | |
| +-	 * normally, except that they will NEVER match rules that ask
 | |
| +-	 * things we don't know, ie. tcp syn flag or ports).  If the
 | |
| +-	 * rule is also a fragment-specific rule, non-fragments won't
 | |
| +-	 * match it. */
 | |
| +-	acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
 | |
| +-	acpar.thoff   = ip_hdrlen(skb);
 | |
| +-	acpar.hotdrop = false;
 | |
| +-	acpar.state   = state;
 | |
| + 
 | |
| +-	WARN_ON(!(table->valid_hooks & (1 << hook)));
 | |
| +-	local_bh_disable();
 | |
| + 	addend = xt_write_recseq_begin();
 | |
| +-	private = READ_ONCE(table->private); /* Address dependency. */
 | |
| +-	cpu        = smp_processor_id();
 | |
| +-	table_base = private->entries;
 | |
| + 	jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
 | |
| + 
 | |
| + 	/* Switch to alternate jumpstack if we're being invoked via TEE.
 | |
| +@@ -299,7 +327,16 @@ ipt_do_table(struct sk_buff *skb,
 | |
| + 	if (static_key_false(&xt_tee_enabled))
 | |
| + 		jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
 | |
| + 
 | |
| +-	e = get_entry(table_base, private->hook_entry[hook]);
 | |
| ++	/* We handle fragments by dealing with the first fragment as
 | |
| ++	 * if it was a normal packet.  All other fragments are treated
 | |
| ++	 * normally, except that they will NEVER match rules that ask
 | |
| ++	 * things we don't know, ie. tcp syn flag or ports).  If the
 | |
| ++	 * rule is also a fragment-specific rule, non-fragments won't
 | |
| ++	 * match it. */
 | |
| ++	acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
 | |
| ++	acpar.thoff   = ip_hdrlen(skb);
 | |
| ++	acpar.hotdrop = false;
 | |
| ++	acpar.state   = state;
 | |
| + 
 | |
| + 	do {
 | |
| + 		const struct xt_entry_target *t;
 | |
| diff --git a/target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch b/target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch
 | |
| new file mode 100644
 | |
| index 0000000000..79da6778b6
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/612-netfilter_match_reduce_memory_access.patch
 | |
| @@ -0,0 +1,22 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: netfilter: reduce match memory access
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + net/ipv4/netfilter/ip_tables.c | 4 ++--
 | |
| + 1 file changed, 2 insertions(+), 2 deletions(-)
 | |
| +
 | |
| +--- a/net/ipv4/netfilter/ip_tables.c
 | |
| ++++ b/net/ipv4/netfilter/ip_tables.c
 | |
| +@@ -53,9 +53,9 @@ ip_packet_match(const struct iphdr *ip,
 | |
| + 	if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
 | |
| + 		return true;
 | |
| + 
 | |
| +-	if (NF_INVF(ipinfo, IPT_INV_SRCIP,
 | |
| ++	if (NF_INVF(ipinfo, IPT_INV_SRCIP, ipinfo->smsk.s_addr &&
 | |
| + 		    (ip->saddr & ipinfo->smsk.s_addr) != ipinfo->src.s_addr) ||
 | |
| +-	    NF_INVF(ipinfo, IPT_INV_DSTIP,
 | |
| ++	    NF_INVF(ipinfo, IPT_INV_DSTIP, ipinfo->dmsk.s_addr &&
 | |
| + 		    (ip->daddr & ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr))
 | |
| + 		return false;
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch b/target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch
 | |
| new file mode 100644
 | |
| index 0000000000..61776921c6
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/613-netfilter_optional_tcp_window_check.patch
 | |
| @@ -0,0 +1,73 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: netfilter: optional tcp window check
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + net/netfilter/nf_conntrack_proto_tcp.c | 13 +++++++++++++
 | |
| + 1 file changed, 13 insertions(+)
 | |
| +
 | |
| +--- a/net/netfilter/nf_conntrack_proto_tcp.c
 | |
| ++++ b/net/netfilter/nf_conntrack_proto_tcp.c
 | |
| +@@ -31,6 +31,9 @@
 | |
| + #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 | |
| + #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
 | |
| + 
 | |
| ++/* Do not check the TCP window for incoming packets  */
 | |
| ++static int nf_ct_tcp_no_window_check __read_mostly = 1;
 | |
| ++
 | |
| + /* "Be conservative in what you do,
 | |
| +     be liberal in what you accept from others."
 | |
| +     If it's non-zero, we mark only out of window RST segments as INVALID. */
 | |
| +@@ -476,6 +479,9 @@ static bool tcp_in_window(const struct n
 | |
| + 	s32 receiver_offset;
 | |
| + 	bool res, in_recv_win;
 | |
| + 
 | |
| ++	if (nf_ct_tcp_no_window_check)
 | |
| ++		return true;
 | |
| ++
 | |
| + 	/*
 | |
| + 	 * Get the required data from the packet.
 | |
| + 	 */
 | |
| +@@ -1130,7 +1136,7 @@ int nf_conntrack_tcp_packet(struct nf_co
 | |
| + 		 IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED &&
 | |
| + 		 timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK])
 | |
| + 		timeout = timeouts[TCP_CONNTRACK_UNACK];
 | |
| +-	else if (ct->proto.tcp.last_win == 0 &&
 | |
| ++	else if (!nf_ct_tcp_no_window_check && ct->proto.tcp.last_win == 0 &&
 | |
| + 		 timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS])
 | |
| + 		timeout = timeouts[TCP_CONNTRACK_RETRANS];
 | |
| + 	else
 | |
| +--- a/net/netfilter/nf_conntrack_standalone.c
 | |
| ++++ b/net/netfilter/nf_conntrack_standalone.c
 | |
| +@@ -25,6 +25,9 @@
 | |
| + #include <net/netfilter/nf_conntrack_timestamp.h>
 | |
| + #include <linux/rculist_nulls.h>
 | |
| + 
 | |
| ++/* Do not check the TCP window for incoming packets  */
 | |
| ++static int nf_ct_tcp_no_window_check __read_mostly = 1;
 | |
| ++
 | |
| + static bool enable_hooks __read_mostly;
 | |
| + MODULE_PARM_DESC(enable_hooks, "Always enable conntrack hooks");
 | |
| + module_param(enable_hooks, bool, 0000);
 | |
| +@@ -651,6 +654,7 @@ enum nf_ct_sysctl_index {
 | |
| + 	NF_SYSCTL_CT_PROTO_TIMEOUT_GRE_STREAM,
 | |
| + #endif
 | |
| + 
 | |
| ++	NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK,
 | |
| + 	__NF_SYSCTL_CT_LAST_SYSCTL,
 | |
| + };
 | |
| + 
 | |
| +@@ -977,6 +981,13 @@ static struct ctl_table nf_ct_sysctl_tab
 | |
| + 		.proc_handler   = proc_dointvec_jiffies,
 | |
| + 	},
 | |
| + #endif
 | |
| ++	[NF_SYSCTL_CT_PROTO_TCP_NO_WINDOW_CHECK] = {
 | |
| ++		.procname       = "nf_conntrack_tcp_no_window_check",
 | |
| ++		.data           = &nf_ct_tcp_no_window_check,
 | |
| ++		.maxlen         = sizeof(unsigned int),
 | |
| ++		.mode           = 0644,
 | |
| ++		.proc_handler   = proc_dointvec,
 | |
| ++	},
 | |
| + 	{}
 | |
| + };
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch b/target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4b4825ae3b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/620-net_sched-codel-do-not-defer-queue-length-update.patch
 | |
| @@ -0,0 +1,86 @@
 | |
| +From: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
 | |
| +Date: Mon, 21 Aug 2017 11:14:14 +0300
 | |
| +Subject: [PATCH] net_sched/codel: do not defer queue length update
 | |
| +
 | |
| +When codel wants to drop last packet in ->dequeue() it cannot call
 | |
| +qdisc_tree_reduce_backlog() right away - it will notify parent qdisc
 | |
| +about zero qlen and HTB/HFSC will deactivate class. The same class will
 | |
| +be deactivated second time by caller of ->dequeue(). Currently codel and
 | |
| +fq_codel defer update. This triggers warning in HFSC when it's qlen != 0
 | |
| +but there is no active classes.
 | |
| +
 | |
| +This patch update parent queue length immediately: just temporary increase
 | |
| +qlen around qdisc_tree_reduce_backlog() to prevent first class deactivation
 | |
| +if we have skb to return.
 | |
| +
 | |
| +This might open another problem in HFSC - now operation peek could fail and
 | |
| +deactivate parent class.
 | |
| +
 | |
| +Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
 | |
| +Link: https://bugzilla.kernel.org/show_bug.cgi?id=109581
 | |
| +---
 | |
| +
 | |
| +--- a/net/sched/sch_codel.c
 | |
| ++++ b/net/sched/sch_codel.c
 | |
| +@@ -95,11 +95,17 @@ static struct sk_buff *codel_qdisc_deque
 | |
| + 			    &q->stats, qdisc_pkt_len, codel_get_enqueue_time,
 | |
| + 			    drop_func, dequeue_func);
 | |
| + 
 | |
| +-	/* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
 | |
| +-	 * or HTB crashes. Defer it for next round.
 | |
| ++	/* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
 | |
| ++	 * parent class, dequeue in parent qdisc will do the same if we
 | |
| ++	 * return skb. Temporary increment qlen if we have skb.
 | |
| + 	 */
 | |
| +-	if (q->stats.drop_count && sch->q.qlen) {
 | |
| +-		qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
 | |
| ++	if (q->stats.drop_count) {
 | |
| ++		if (skb)
 | |
| ++			sch->q.qlen++;
 | |
| ++		qdisc_tree_reduce_backlog(sch, q->stats.drop_count,
 | |
| ++					  q->stats.drop_len);
 | |
| ++		if (skb)
 | |
| ++			sch->q.qlen--;
 | |
| + 		q->stats.drop_count = 0;
 | |
| + 		q->stats.drop_len = 0;
 | |
| + 	}
 | |
| +--- a/net/sched/sch_fq_codel.c
 | |
| ++++ b/net/sched/sch_fq_codel.c
 | |
| +@@ -304,6 +304,21 @@ begin:
 | |
| + 			    &flow->cvars, &q->cstats, qdisc_pkt_len,
 | |
| + 			    codel_get_enqueue_time, drop_func, dequeue_func);
 | |
| + 
 | |
| ++	/* If our qlen is 0 qdisc_tree_reduce_backlog() will deactivate
 | |
| ++	 * parent class, dequeue in parent qdisc will do the same if we
 | |
| ++	 * return skb. Temporary increment qlen if we have skb.
 | |
| ++	 */
 | |
| ++	if (q->cstats.drop_count) {
 | |
| ++		if (skb)
 | |
| ++			sch->q.qlen++;
 | |
| ++		qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
 | |
| ++					  q->cstats.drop_len);
 | |
| ++		if (skb)
 | |
| ++			sch->q.qlen--;
 | |
| ++		q->cstats.drop_count = 0;
 | |
| ++		q->cstats.drop_len = 0;
 | |
| ++	}
 | |
| ++
 | |
| + 	if (!skb) {
 | |
| + 		/* force a pass through old_flows to prevent starvation */
 | |
| + 		if ((head == &q->new_flows) && !list_empty(&q->old_flows))
 | |
| +@@ -314,15 +329,6 @@ begin:
 | |
| + 	}
 | |
| + 	qdisc_bstats_update(sch, skb);
 | |
| + 	flow->deficit -= qdisc_pkt_len(skb);
 | |
| +-	/* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
 | |
| +-	 * or HTB crashes. Defer it for next round.
 | |
| +-	 */
 | |
| +-	if (q->cstats.drop_count && sch->q.qlen) {
 | |
| +-		qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
 | |
| +-					  q->cstats.drop_len);
 | |
| +-		q->cstats.drop_count = 0;
 | |
| +-		q->cstats.drop_len = 0;
 | |
| +-	}
 | |
| + 	return skb;
 | |
| + }
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/630-packet_socket_type.patch b/target/linux/generic/pending-5.10/630-packet_socket_type.patch
 | |
| new file mode 100644
 | |
| index 0000000000..104bcbe5a5
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/630-packet_socket_type.patch
 | |
| @@ -0,0 +1,138 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: net: add an optimization for dealing with raw sockets
 | |
| +
 | |
| +lede-commit: 4898039703d7315f0f3431c860123338ec3be0f6
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/uapi/linux/if_packet.h |  3 +++
 | |
| + net/packet/af_packet.c         | 34 +++++++++++++++++++++++++++-------
 | |
| + net/packet/internal.h          |  1 +
 | |
| + 3 files changed, 31 insertions(+), 7 deletions(-)
 | |
| +
 | |
| +--- a/include/uapi/linux/if_packet.h
 | |
| ++++ b/include/uapi/linux/if_packet.h
 | |
| +@@ -32,6 +32,8 @@ struct sockaddr_ll {
 | |
| + #define PACKET_KERNEL		7		/* To kernel space	*/
 | |
| + /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
 | |
| + #define PACKET_FASTROUTE	6		/* Fastrouted frame	*/
 | |
| ++#define PACKET_MASK_ANY		0xffffffff	/* mask for packet type bits */
 | |
| ++
 | |
| + 
 | |
| + /* Packet socket options */
 | |
| + 
 | |
| +@@ -58,6 +60,7 @@ struct sockaddr_ll {
 | |
| + #define PACKET_ROLLOVER_STATS		21
 | |
| + #define PACKET_FANOUT_DATA		22
 | |
| + #define PACKET_IGNORE_OUTGOING		23
 | |
| ++#define PACKET_RECV_TYPE		24
 | |
| + 
 | |
| + #define PACKET_FANOUT_HASH		0
 | |
| + #define PACKET_FANOUT_LB		1
 | |
| +--- a/net/packet/af_packet.c
 | |
| ++++ b/net/packet/af_packet.c
 | |
| +@@ -1801,6 +1801,7 @@ static int packet_rcv_spkt(struct sk_buf
 | |
| + {
 | |
| + 	struct sock *sk;
 | |
| + 	struct sockaddr_pkt *spkt;
 | |
| ++	struct packet_sock *po;
 | |
| + 
 | |
| + 	/*
 | |
| + 	 *	When we registered the protocol we saved the socket in the data
 | |
| +@@ -1808,6 +1809,7 @@ static int packet_rcv_spkt(struct sk_buf
 | |
| + 	 */
 | |
| + 
 | |
| + 	sk = pt->af_packet_priv;
 | |
| ++	po = pkt_sk(sk);
 | |
| + 
 | |
| + 	/*
 | |
| + 	 *	Yank back the headers [hope the device set this
 | |
| +@@ -1820,7 +1822,7 @@ static int packet_rcv_spkt(struct sk_buf
 | |
| + 	 *	so that this procedure is noop.
 | |
| + 	 */
 | |
| + 
 | |
| +-	if (skb->pkt_type == PACKET_LOOPBACK)
 | |
| ++	if (!(po->pkt_type & (1 << skb->pkt_type)))
 | |
| + 		goto out;
 | |
| + 
 | |
| + 	if (!net_eq(dev_net(dev), sock_net(sk)))
 | |
| +@@ -2058,12 +2060,12 @@ static int packet_rcv(struct sk_buff *sk
 | |
| + 	unsigned int snaplen, res;
 | |
| + 	bool is_drop_n_account = false;
 | |
| + 
 | |
| +-	if (skb->pkt_type == PACKET_LOOPBACK)
 | |
| +-		goto drop;
 | |
| +-
 | |
| + 	sk = pt->af_packet_priv;
 | |
| + 	po = pkt_sk(sk);
 | |
| + 
 | |
| ++	if (!(po->pkt_type & (1 << skb->pkt_type)))
 | |
| ++		goto drop;
 | |
| ++
 | |
| + 	if (!net_eq(dev_net(dev), sock_net(sk)))
 | |
| + 		goto drop;
 | |
| + 
 | |
| +@@ -2189,12 +2191,12 @@ static int tpacket_rcv(struct sk_buff *s
 | |
| + 	BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h2)) != 32);
 | |
| + 	BUILD_BUG_ON(TPACKET_ALIGN(sizeof(*h.h3)) != 48);
 | |
| + 
 | |
| +-	if (skb->pkt_type == PACKET_LOOPBACK)
 | |
| +-		goto drop;
 | |
| +-
 | |
| + 	sk = pt->af_packet_priv;
 | |
| + 	po = pkt_sk(sk);
 | |
| + 
 | |
| ++	if (!(po->pkt_type & (1 << skb->pkt_type)))
 | |
| ++		goto drop;
 | |
| ++
 | |
| + 	if (!net_eq(dev_net(dev), sock_net(sk)))
 | |
| + 		goto drop;
 | |
| + 
 | |
| +@@ -3293,6 +3295,7 @@ static int packet_create(struct net *net
 | |
| + 	mutex_init(&po->pg_vec_lock);
 | |
| + 	po->rollover = NULL;
 | |
| + 	po->prot_hook.func = packet_rcv;
 | |
| ++	po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
 | |
| + 
 | |
| + 	if (sock->type == SOCK_PACKET)
 | |
| + 		po->prot_hook.func = packet_rcv_spkt;
 | |
| +@@ -3927,6 +3930,16 @@ packet_setsockopt(struct socket *sock, i
 | |
| + 		po->xmit = val ? packet_direct_xmit : dev_queue_xmit;
 | |
| + 		return 0;
 | |
| + 	}
 | |
| ++	case PACKET_RECV_TYPE:
 | |
| ++	{
 | |
| ++		unsigned int val;
 | |
| ++		if (optlen != sizeof(val))
 | |
| ++			return -EINVAL;
 | |
| ++		if (copy_from_sockptr(&val, optval, sizeof(val)))
 | |
| ++			return -EFAULT;
 | |
| ++		po->pkt_type = val & ~BIT(PACKET_LOOPBACK);
 | |
| ++		return 0;
 | |
| ++	}
 | |
| + 	default:
 | |
| + 		return -ENOPROTOOPT;
 | |
| + 	}
 | |
| +@@ -3983,6 +3996,13 @@ static int packet_getsockopt(struct sock
 | |
| + 	case PACKET_VNET_HDR:
 | |
| + 		val = po->has_vnet_hdr;
 | |
| + 		break;
 | |
| ++	case PACKET_RECV_TYPE:
 | |
| ++		if (len > sizeof(unsigned int))
 | |
| ++			len = sizeof(unsigned int);
 | |
| ++		val = po->pkt_type;
 | |
| ++
 | |
| ++		data = &val;
 | |
| ++		break;
 | |
| + 	case PACKET_VERSION:
 | |
| + 		val = po->tp_version;
 | |
| + 		break;
 | |
| +--- a/net/packet/internal.h
 | |
| ++++ b/net/packet/internal.h
 | |
| +@@ -136,6 +136,7 @@ struct packet_sock {
 | |
| + 	int			(*xmit)(struct sk_buff *skb);
 | |
| + 	struct packet_type	prot_hook ____cacheline_aligned_in_smp;
 | |
| + 	atomic_t		tp_drops ____cacheline_aligned_in_smp;
 | |
| ++	unsigned int		pkt_type;
 | |
| + };
 | |
| + 
 | |
| + static struct packet_sock *pkt_sk(struct sock *sk)
 | |
| diff --git a/target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch b/target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch
 | |
| new file mode 100644
 | |
| index 0000000000..c881ccfcb0
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-00-netfilter-flowtable-add-hash-offset-field-to-tuple.patch
 | |
| @@ -0,0 +1,52 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Fri, 20 Nov 2020 13:49:13 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: add hash offset field to tuple
 | |
| +
 | |
| +Add a placeholder field to calculate hash tuple offset. Similar to
 | |
| +2c407aca6497 ("netfilter: conntrack: avoid gcc-10 zero-length-bounds
 | |
| +warning").
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -107,6 +107,10 @@ struct flow_offload_tuple {
 | |
| + 
 | |
| + 	u8				l3proto;
 | |
| + 	u8				l4proto;
 | |
| ++
 | |
| ++	/* All members above are keys for lookups, see flow_offload_hash(). */
 | |
| ++	struct { }			__hash;
 | |
| ++
 | |
| + 	u8				dir;
 | |
| + 
 | |
| + 	u16				mtu;
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -191,14 +191,14 @@ static u32 flow_offload_hash(const void
 | |
| + {
 | |
| + 	const struct flow_offload_tuple *tuple = data;
 | |
| + 
 | |
| +-	return jhash(tuple, offsetof(struct flow_offload_tuple, dir), seed);
 | |
| ++	return jhash(tuple, offsetof(struct flow_offload_tuple, __hash), seed);
 | |
| + }
 | |
| + 
 | |
| + static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed)
 | |
| + {
 | |
| + 	const struct flow_offload_tuple_rhash *tuplehash = data;
 | |
| + 
 | |
| +-	return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, dir), seed);
 | |
| ++	return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, __hash), seed);
 | |
| + }
 | |
| + 
 | |
| + static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg,
 | |
| +@@ -207,7 +207,7 @@ static int flow_offload_hash_cmp(struct
 | |
| + 	const struct flow_offload_tuple *tuple = arg->key;
 | |
| + 	const struct flow_offload_tuple_rhash *x = ptr;
 | |
| + 
 | |
| +-	if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, dir)))
 | |
| ++	if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, __hash)))
 | |
| + 		return 1;
 | |
| + 
 | |
| + 	return 0;
 | |
| diff --git a/target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch b/target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e47d03e48d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-01-netfilter-flowtable-add-xmit-path-types.patch
 | |
| @@ -0,0 +1,188 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Fri, 20 Nov 2020 13:49:14 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: add xmit path types
 | |
| +
 | |
| +Add the xmit_type field that defines the two supported xmit paths in the
 | |
| +flowtable data plane, which are the neighbour and the xfrm xmit paths.
 | |
| +This patch prepares for new flowtable xmit path types to come.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -89,6 +89,11 @@ enum flow_offload_tuple_dir {
 | |
| + 	FLOW_OFFLOAD_DIR_MAX = IP_CT_DIR_MAX
 | |
| + };
 | |
| + 
 | |
| ++enum flow_offload_xmit_type {
 | |
| ++	FLOW_OFFLOAD_XMIT_NEIGH		= 0,
 | |
| ++	FLOW_OFFLOAD_XMIT_XFRM,
 | |
| ++};
 | |
| ++
 | |
| + struct flow_offload_tuple {
 | |
| + 	union {
 | |
| + 		struct in_addr		src_v4;
 | |
| +@@ -111,7 +116,8 @@ struct flow_offload_tuple {
 | |
| + 	/* All members above are keys for lookups, see flow_offload_hash(). */
 | |
| + 	struct { }			__hash;
 | |
| + 
 | |
| +-	u8				dir;
 | |
| ++	u8				dir:6,
 | |
| ++					xmit_type:2;
 | |
| + 
 | |
| + 	u16				mtu;
 | |
| + 
 | |
| +@@ -158,7 +164,8 @@ static inline __s32 nf_flow_timeout_delt
 | |
| + 
 | |
| + struct nf_flow_route {
 | |
| + 	struct {
 | |
| +-		struct dst_entry	*dst;
 | |
| ++		struct dst_entry		*dst;
 | |
| ++		enum flow_offload_xmit_type	xmit_type;
 | |
| + 	} tuple[FLOW_OFFLOAD_DIR_MAX];
 | |
| + };
 | |
| + 
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -95,6 +95,7 @@ static int flow_offload_fill_route(struc
 | |
| + 	}
 | |
| + 
 | |
| + 	flow_tuple->iifidx = other_dst->dev->ifindex;
 | |
| ++	flow_tuple->xmit_type = route->tuple[dir].xmit_type;
 | |
| + 	flow_tuple->dst_cache = dst;
 | |
| + 
 | |
| + 	return 0;
 | |
| +--- a/net/netfilter/nf_flow_table_ip.c
 | |
| ++++ b/net/netfilter/nf_flow_table_ip.c
 | |
| +@@ -220,10 +220,20 @@ static bool nf_flow_exceeds_mtu(const st
 | |
| + 	return true;
 | |
| + }
 | |
| + 
 | |
| +-static int nf_flow_offload_dst_check(struct dst_entry *dst)
 | |
| ++static inline struct dst_entry *
 | |
| ++nft_flow_dst(struct flow_offload_tuple_rhash *tuplehash)
 | |
| + {
 | |
| +-	if (unlikely(dst_xfrm(dst)))
 | |
| ++	return tuplehash->tuple.dst_cache;
 | |
| ++}
 | |
| ++
 | |
| ++static int nf_flow_offload_dst_check(struct flow_offload_tuple_rhash *tuplehash)
 | |
| ++{
 | |
| ++	struct dst_entry *dst;
 | |
| ++
 | |
| ++	if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
 | |
| ++		dst = nft_flow_dst(tuplehash);
 | |
| + 		return dst_check(dst, 0) ? 0 : -1;
 | |
| ++	}
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -265,8 +275,6 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 
 | |
| + 	dir = tuplehash->tuple.dir;
 | |
| + 	flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
 | |
| +-	rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
 | |
| +-	outdev = rt->dst.dev;
 | |
| + 
 | |
| + 	if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
 | |
| + 		return NF_ACCEPT;
 | |
| +@@ -280,7 +288,7 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 
 | |
| + 	flow_offload_refresh(flow_table, flow);
 | |
| + 
 | |
| +-	if (nf_flow_offload_dst_check(&rt->dst)) {
 | |
| ++	if (nf_flow_offload_dst_check(tuplehash)) {
 | |
| + 		flow_offload_teardown(flow);
 | |
| + 		return NF_ACCEPT;
 | |
| + 	}
 | |
| +@@ -295,13 +303,16 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 	if (flow_table->flags & NF_FLOWTABLE_COUNTER)
 | |
| + 		nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
 | |
| + 
 | |
| +-	if (unlikely(dst_xfrm(&rt->dst))) {
 | |
| ++	rt = (struct rtable *)tuplehash->tuple.dst_cache;
 | |
| ++
 | |
| ++	if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
 | |
| + 		memset(skb->cb, 0, sizeof(struct inet_skb_parm));
 | |
| + 		IPCB(skb)->iif = skb->dev->ifindex;
 | |
| + 		IPCB(skb)->flags = IPSKB_FORWARDED;
 | |
| + 		return nf_flow_xmit_xfrm(skb, state, &rt->dst);
 | |
| + 	}
 | |
| + 
 | |
| ++	outdev = rt->dst.dev;
 | |
| + 	skb->dev = outdev;
 | |
| + 	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
 | |
| + 	skb_dst_set_noref(skb, &rt->dst);
 | |
| +@@ -506,8 +517,6 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 
 | |
| + 	dir = tuplehash->tuple.dir;
 | |
| + 	flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
 | |
| +-	rt = (struct rt6_info *)flow->tuplehash[dir].tuple.dst_cache;
 | |
| +-	outdev = rt->dst.dev;
 | |
| + 
 | |
| + 	if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
 | |
| + 		return NF_ACCEPT;
 | |
| +@@ -518,7 +527,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 
 | |
| + 	flow_offload_refresh(flow_table, flow);
 | |
| + 
 | |
| +-	if (nf_flow_offload_dst_check(&rt->dst)) {
 | |
| ++	if (nf_flow_offload_dst_check(tuplehash)) {
 | |
| + 		flow_offload_teardown(flow);
 | |
| + 		return NF_ACCEPT;
 | |
| + 	}
 | |
| +@@ -536,13 +545,16 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 	if (flow_table->flags & NF_FLOWTABLE_COUNTER)
 | |
| + 		nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
 | |
| + 
 | |
| +-	if (unlikely(dst_xfrm(&rt->dst))) {
 | |
| ++	rt = (struct rt6_info *)tuplehash->tuple.dst_cache;
 | |
| ++
 | |
| ++	if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
 | |
| + 		memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
 | |
| + 		IP6CB(skb)->iif = skb->dev->ifindex;
 | |
| + 		IP6CB(skb)->flags = IP6SKB_FORWARDED;
 | |
| + 		return nf_flow_xmit_xfrm(skb, state, &rt->dst);
 | |
| + 	}
 | |
| + 
 | |
| ++	outdev = rt->dst.dev;
 | |
| + 	skb->dev = outdev;
 | |
| + 	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
 | |
| + 	skb_dst_set_noref(skb, &rt->dst);
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -19,6 +19,22 @@ struct nft_flow_offload {
 | |
| + 	struct nft_flowtable	*flowtable;
 | |
| + };
 | |
| + 
 | |
| ++static enum flow_offload_xmit_type nft_xmit_type(struct dst_entry *dst)
 | |
| ++{
 | |
| ++	if (dst_xfrm(dst))
 | |
| ++		return FLOW_OFFLOAD_XMIT_XFRM;
 | |
| ++
 | |
| ++	return FLOW_OFFLOAD_XMIT_NEIGH;
 | |
| ++}
 | |
| ++
 | |
| ++static void nft_default_forward_path(struct nf_flow_route *route,
 | |
| ++				     struct dst_entry *dst_cache,
 | |
| ++				     enum ip_conntrack_dir dir)
 | |
| ++{
 | |
| ++	route->tuple[dir].dst		= dst_cache;
 | |
| ++	route->tuple[dir].xmit_type	= nft_xmit_type(dst_cache);
 | |
| ++}
 | |
| ++
 | |
| + static int nft_flow_route(const struct nft_pktinfo *pkt,
 | |
| + 			  const struct nf_conn *ct,
 | |
| + 			  struct nf_flow_route *route,
 | |
| +@@ -44,8 +60,8 @@ static int nft_flow_route(const struct n
 | |
| + 	if (!other_dst)
 | |
| + 		return -ENOENT;
 | |
| + 
 | |
| +-	route->tuple[dir].dst		= this_dst;
 | |
| +-	route->tuple[!dir].dst		= other_dst;
 | |
| ++	nft_default_forward_path(route, this_dst, dir);
 | |
| ++	nft_default_forward_path(route, other_dst, !dir);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch b/target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch
 | |
| new file mode 100644
 | |
| index 0000000000..224831d593
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-02-net-resolve-forwarding-path-from-virtual-netdevice-a.patch
 | |
| @@ -0,0 +1,170 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Thu, 4 Mar 2021 23:18:11 +0100
 | |
| +Subject: [PATCH] net: resolve forwarding path from virtual netdevice and
 | |
| + HW destination address
 | |
| +
 | |
| +This patch adds dev_fill_forward_path() which resolves the path to reach
 | |
| +the real netdevice from the IP forwarding side. This function takes as
 | |
| +input the netdevice and the destination hardware address and it walks
 | |
| +down the devices calling .ndo_fill_forward_path() for each device until
 | |
| +the real device is found.
 | |
| +
 | |
| +For instance, assuming the following topology:
 | |
| +
 | |
| +               IP forwarding
 | |
| +              /             \
 | |
| +           br0              eth0
 | |
| +           / \
 | |
| +       eth1  eth2
 | |
| +        .
 | |
| +        .
 | |
| +        .
 | |
| +       ethX
 | |
| + ab:cd:ef:ab:cd:ef
 | |
| +
 | |
| +where eth1 and eth2 are bridge ports and eth0 provides WAN connectivity.
 | |
| +ethX is the interface in another box which is connected to the eth1
 | |
| +bridge port.
 | |
| +
 | |
| +For packets going through IP forwarding to br0 whose destination MAC
 | |
| +address is ab:cd:ef:ab:cd:ef, dev_fill_forward_path() provides the
 | |
| +following path:
 | |
| +
 | |
| +	br0 -> eth1
 | |
| +
 | |
| +.ndo_fill_forward_path for br0 looks up at the FDB for the bridge port
 | |
| +from the destination MAC address to get the bridge port eth1.
 | |
| +
 | |
| +This information allows to create a fast path that bypasses the classic
 | |
| +bridge and IP forwarding paths, so packets go directly from the bridge
 | |
| +port eth1 to eth0 (wan interface) and vice versa.
 | |
| +
 | |
| +             fast path
 | |
| +      .------------------------.
 | |
| +     /                          \
 | |
| +    |           IP forwarding   |
 | |
| +    |          /             \  \/
 | |
| +    |       br0               eth0
 | |
| +    .       / \
 | |
| +     -> eth1  eth2
 | |
| +        .
 | |
| +        .
 | |
| +        .
 | |
| +       ethX
 | |
| + ab:cd:ef:ab:cd:ef
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -827,6 +827,27 @@ typedef u16 (*select_queue_fallback_t)(s
 | |
| + 				       struct sk_buff *skb,
 | |
| + 				       struct net_device *sb_dev);
 | |
| + 
 | |
| ++enum net_device_path_type {
 | |
| ++	DEV_PATH_ETHERNET = 0,
 | |
| ++};
 | |
| ++
 | |
| ++struct net_device_path {
 | |
| ++	enum net_device_path_type	type;
 | |
| ++	const struct net_device		*dev;
 | |
| ++};
 | |
| ++
 | |
| ++#define NET_DEVICE_PATH_STACK_MAX	5
 | |
| ++
 | |
| ++struct net_device_path_stack {
 | |
| ++	int			num_paths;
 | |
| ++	struct net_device_path	path[NET_DEVICE_PATH_STACK_MAX];
 | |
| ++};
 | |
| ++
 | |
| ++struct net_device_path_ctx {
 | |
| ++	const struct net_device *dev;
 | |
| ++	const u8		*daddr;
 | |
| ++};
 | |
| ++
 | |
| + enum tc_setup_type {
 | |
| + 	TC_SETUP_QDISC_MQPRIO,
 | |
| + 	TC_SETUP_CLSU32,
 | |
| +@@ -1273,6 +1294,8 @@ struct netdev_net_notifier {
 | |
| +  * struct net_device *(*ndo_get_peer_dev)(struct net_device *dev);
 | |
| +  *	If a device is paired with a peer device, return the peer instance.
 | |
| +  *	The caller must be under RCU read context.
 | |
| ++ * int (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx, struct net_device_path *path);
 | |
| ++ *     Get the forwarding path to reach the real device from the HW destination address
 | |
| +  */
 | |
| + struct net_device_ops {
 | |
| + 	int			(*ndo_init)(struct net_device *dev);
 | |
| +@@ -1481,6 +1504,8 @@ struct net_device_ops {
 | |
| + 	int			(*ndo_tunnel_ctl)(struct net_device *dev,
 | |
| + 						  struct ip_tunnel_parm *p, int cmd);
 | |
| + 	struct net_device *	(*ndo_get_peer_dev)(struct net_device *dev);
 | |
| ++	int                     (*ndo_fill_forward_path)(struct net_device_path_ctx *ctx,
 | |
| ++                                                         struct net_device_path *path);
 | |
| + };
 | |
| + 
 | |
| + /**
 | |
| +@@ -2795,6 +2820,8 @@ void dev_remove_offload(struct packet_of
 | |
| + 
 | |
| + int dev_get_iflink(const struct net_device *dev);
 | |
| + int dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb);
 | |
| ++int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
 | |
| ++			  struct net_device_path_stack *stack);
 | |
| + struct net_device *__dev_get_by_flags(struct net *net, unsigned short flags,
 | |
| + 				      unsigned short mask);
 | |
| + struct net_device *dev_get_by_name(struct net *net, const char *name);
 | |
| +--- a/net/core/dev.c
 | |
| ++++ b/net/core/dev.c
 | |
| +@@ -847,6 +847,52 @@ int dev_fill_metadata_dst(struct net_dev
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(dev_fill_metadata_dst);
 | |
| + 
 | |
| ++static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack)
 | |
| ++{
 | |
| ++	int k = stack->num_paths++;
 | |
| ++
 | |
| ++	if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX))
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	return &stack->path[k];
 | |
| ++}
 | |
| ++
 | |
| ++int dev_fill_forward_path(const struct net_device *dev, const u8 *daddr,
 | |
| ++			  struct net_device_path_stack *stack)
 | |
| ++{
 | |
| ++	const struct net_device *last_dev;
 | |
| ++	struct net_device_path_ctx ctx = {
 | |
| ++		.dev	= dev,
 | |
| ++		.daddr	= daddr,
 | |
| ++	};
 | |
| ++	struct net_device_path *path;
 | |
| ++	int ret = 0;
 | |
| ++
 | |
| ++	stack->num_paths = 0;
 | |
| ++	while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) {
 | |
| ++		last_dev = ctx.dev;
 | |
| ++		path = dev_fwd_path(stack);
 | |
| ++		if (!path)
 | |
| ++			return -1;
 | |
| ++
 | |
| ++		memset(path, 0, sizeof(struct net_device_path));
 | |
| ++		ret = ctx.dev->netdev_ops->ndo_fill_forward_path(&ctx, path);
 | |
| ++		if (ret < 0)
 | |
| ++			return -1;
 | |
| ++
 | |
| ++		if (WARN_ON_ONCE(last_dev == ctx.dev))
 | |
| ++			return -1;
 | |
| ++	}
 | |
| ++	path = dev_fwd_path(stack);
 | |
| ++	if (!path)
 | |
| ++		return -1;
 | |
| ++	path->type = DEV_PATH_ETHERNET;
 | |
| ++	path->dev = ctx.dev;
 | |
| ++
 | |
| ++	return ret;
 | |
| ++}
 | |
| ++EXPORT_SYMBOL_GPL(dev_fill_forward_path);
 | |
| ++
 | |
| + /**
 | |
| +  *	__dev_get_by_name	- find a device by its name
 | |
| +  *	@net: the applicable net namespace
 | |
| diff --git a/target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch b/target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch
 | |
| new file mode 100644
 | |
| index 0000000000..69e025be26
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-03-net-8021q-resolve-forwarding-path-for-vlan-devices.patch
 | |
| @@ -0,0 +1,80 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Fri, 20 Nov 2020 13:49:16 +0100
 | |
| +Subject: [PATCH] net: 8021q: resolve forwarding path for vlan devices
 | |
| +
 | |
| +Add .ndo_fill_forward_path for vlan devices.
 | |
| +
 | |
| +For instance, assuming the following topology:
 | |
| +
 | |
| +                   IP forwarding
 | |
| +                  /             \
 | |
| +            eth0.100             eth0
 | |
| +            |
 | |
| +            eth0
 | |
| +            .
 | |
| +            .
 | |
| +            .
 | |
| +           ethX
 | |
| +     ab:cd:ef:ab:cd:ef
 | |
| +
 | |
| +For packets going through IP forwarding to eth0.100 whose destination
 | |
| +MAC address is ab:cd:ef:ab:cd:ef, dev_fill_forward_path() provides the
 | |
| +following path:
 | |
| +
 | |
| +        eth0.100 -> eth0
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -829,11 +829,18 @@ typedef u16 (*select_queue_fallback_t)(s
 | |
| + 
 | |
| + enum net_device_path_type {
 | |
| + 	DEV_PATH_ETHERNET = 0,
 | |
| ++	DEV_PATH_VLAN,
 | |
| + };
 | |
| + 
 | |
| + struct net_device_path {
 | |
| + 	enum net_device_path_type	type;
 | |
| + 	const struct net_device		*dev;
 | |
| ++	union {
 | |
| ++		struct {
 | |
| ++			u16		id;
 | |
| ++			__be16		proto;
 | |
| ++		} encap;
 | |
| ++	};
 | |
| + };
 | |
| + 
 | |
| + #define NET_DEVICE_PATH_STACK_MAX	5
 | |
| +--- a/net/8021q/vlan_dev.c
 | |
| ++++ b/net/8021q/vlan_dev.c
 | |
| +@@ -767,6 +767,20 @@ static int vlan_dev_get_iflink(const str
 | |
| + 	return real_dev->ifindex;
 | |
| + }
 | |
| + 
 | |
| ++static int vlan_dev_fill_forward_path(struct net_device_path_ctx *ctx,
 | |
| ++				      struct net_device_path *path)
 | |
| ++{
 | |
| ++	struct vlan_dev_priv *vlan = vlan_dev_priv(ctx->dev);
 | |
| ++
 | |
| ++	path->type = DEV_PATH_VLAN;
 | |
| ++	path->encap.id = vlan->vlan_id;
 | |
| ++	path->encap.proto = vlan->vlan_proto;
 | |
| ++	path->dev = ctx->dev;
 | |
| ++	ctx->dev = vlan->real_dev;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static const struct ethtool_ops vlan_ethtool_ops = {
 | |
| + 	.get_link_ksettings	= vlan_ethtool_get_link_ksettings,
 | |
| + 	.get_drvinfo	        = vlan_ethtool_get_drvinfo,
 | |
| +@@ -805,6 +819,7 @@ static const struct net_device_ops vlan_
 | |
| + #endif
 | |
| + 	.ndo_fix_features	= vlan_dev_fix_features,
 | |
| + 	.ndo_get_iflink		= vlan_dev_get_iflink,
 | |
| ++	.ndo_fill_forward_path	= vlan_dev_fill_forward_path,
 | |
| + };
 | |
| + 
 | |
| + static void vlan_dev_free(struct net_device *dev)
 | |
| diff --git a/target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch b/target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch
 | |
| new file mode 100644
 | |
| index 0000000000..cfb817f20f
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-04-bridge-resolve-forwarding-path-for-bridge-devices.patch
 | |
| @@ -0,0 +1,62 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Fri, 20 Nov 2020 13:49:17 +0100
 | |
| +Subject: [PATCH] bridge: resolve forwarding path for bridge devices
 | |
| +
 | |
| +Add .ndo_fill_forward_path for bridge devices.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -830,6 +830,7 @@ typedef u16 (*select_queue_fallback_t)(s
 | |
| + enum net_device_path_type {
 | |
| + 	DEV_PATH_ETHERNET = 0,
 | |
| + 	DEV_PATH_VLAN,
 | |
| ++	DEV_PATH_BRIDGE,
 | |
| + };
 | |
| + 
 | |
| + struct net_device_path {
 | |
| +--- a/net/bridge/br_device.c
 | |
| ++++ b/net/bridge/br_device.c
 | |
| +@@ -398,6 +398,32 @@ static int br_del_slave(struct net_devic
 | |
| + 	return br_del_if(br, slave_dev);
 | |
| + }
 | |
| + 
 | |
| ++static int br_fill_forward_path(struct net_device_path_ctx *ctx,
 | |
| ++				struct net_device_path *path)
 | |
| ++{
 | |
| ++	struct net_bridge_fdb_entry *f;
 | |
| ++	struct net_bridge_port *dst;
 | |
| ++	struct net_bridge *br;
 | |
| ++
 | |
| ++	if (netif_is_bridge_port(ctx->dev))
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	br = netdev_priv(ctx->dev);
 | |
| ++	f = br_fdb_find_rcu(br, ctx->daddr, 0);
 | |
| ++	if (!f || !f->dst)
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	dst = READ_ONCE(f->dst);
 | |
| ++	if (!dst)
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	path->type = DEV_PATH_BRIDGE;
 | |
| ++	path->dev = dst->br->dev;
 | |
| ++	ctx->dev = dst->dev;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static const struct ethtool_ops br_ethtool_ops = {
 | |
| + 	.get_drvinfo		 = br_getinfo,
 | |
| + 	.get_link		 = ethtool_op_get_link,
 | |
| +@@ -432,6 +458,7 @@ static const struct net_device_ops br_ne
 | |
| + 	.ndo_bridge_setlink	 = br_setlink,
 | |
| + 	.ndo_bridge_dellink	 = br_dellink,
 | |
| + 	.ndo_features_check	 = passthru_features_check,
 | |
| ++	.ndo_fill_forward_path	 = br_fill_forward_path,
 | |
| + };
 | |
| + 
 | |
| + static struct device_type br_type = {
 | |
| diff --git a/target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch b/target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1f61cff09d
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-05-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch
 | |
| @@ -0,0 +1,191 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Fri, 20 Nov 2020 13:49:18 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: use dev_fill_forward_path() to
 | |
| + obtain ingress device
 | |
| +
 | |
| +Obtain the ingress device in the tuple from the route in the reply
 | |
| +direction. Use dev_fill_forward_path() instead to get the real ingress
 | |
| +device for this flow.
 | |
| +
 | |
| +Fall back to use the ingress device that the IP forwarding route
 | |
| +provides if:
 | |
| +
 | |
| +- dev_fill_forward_path() finds no real ingress device.
 | |
| +- the ingress device that is obtained is not part of the flowtable
 | |
| +  devices.
 | |
| +- this route has a xfrm policy.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -165,6 +165,9 @@ static inline __s32 nf_flow_timeout_delt
 | |
| + struct nf_flow_route {
 | |
| + 	struct {
 | |
| + 		struct dst_entry		*dst;
 | |
| ++		struct {
 | |
| ++			u32			ifindex;
 | |
| ++		} in;
 | |
| + 		enum flow_offload_xmit_type	xmit_type;
 | |
| + 	} tuple[FLOW_OFFLOAD_DIR_MAX];
 | |
| + };
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -79,7 +79,6 @@ static int flow_offload_fill_route(struc
 | |
| + 				   enum flow_offload_tuple_dir dir)
 | |
| + {
 | |
| + 	struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
 | |
| +-	struct dst_entry *other_dst = route->tuple[!dir].dst;
 | |
| + 	struct dst_entry *dst = route->tuple[dir].dst;
 | |
| + 
 | |
| + 	if (!dst_hold_safe(route->tuple[dir].dst))
 | |
| +@@ -94,7 +93,7 @@ static int flow_offload_fill_route(struc
 | |
| + 		break;
 | |
| + 	}
 | |
| + 
 | |
| +-	flow_tuple->iifidx = other_dst->dev->ifindex;
 | |
| ++	flow_tuple->iifidx = route->tuple[dir].in.ifindex;
 | |
| + 	flow_tuple->xmit_type = route->tuple[dir].xmit_type;
 | |
| + 	flow_tuple->dst_cache = dst;
 | |
| + 
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -31,14 +31,104 @@ static void nft_default_forward_path(str
 | |
| + 				     struct dst_entry *dst_cache,
 | |
| + 				     enum ip_conntrack_dir dir)
 | |
| + {
 | |
| ++	route->tuple[!dir].in.ifindex	= dst_cache->dev->ifindex;
 | |
| + 	route->tuple[dir].dst		= dst_cache;
 | |
| + 	route->tuple[dir].xmit_type	= nft_xmit_type(dst_cache);
 | |
| + }
 | |
| + 
 | |
| ++static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
 | |
| ++				     const struct dst_entry *dst_cache,
 | |
| ++				     const struct nf_conn *ct,
 | |
| ++				     enum ip_conntrack_dir dir,
 | |
| ++				     struct net_device_path_stack *stack)
 | |
| ++{
 | |
| ++	const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
 | |
| ++	struct net_device *dev = dst_cache->dev;
 | |
| ++	unsigned char ha[ETH_ALEN];
 | |
| ++	struct neighbour *n;
 | |
| ++	u8 nud_state;
 | |
| ++
 | |
| ++	n = dst_neigh_lookup(dst_cache, daddr);
 | |
| ++	if (!n)
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	read_lock_bh(&n->lock);
 | |
| ++	nud_state = n->nud_state;
 | |
| ++	ether_addr_copy(ha, n->ha);
 | |
| ++	read_unlock_bh(&n->lock);
 | |
| ++	neigh_release(n);
 | |
| ++
 | |
| ++	if (!(nud_state & NUD_VALID))
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	return dev_fill_forward_path(dev, ha, stack);
 | |
| ++}
 | |
| ++
 | |
| ++struct nft_forward_info {
 | |
| ++	const struct net_device *indev;
 | |
| ++};
 | |
| ++
 | |
| ++static void nft_dev_path_info(const struct net_device_path_stack *stack,
 | |
| ++			      struct nft_forward_info *info)
 | |
| ++{
 | |
| ++	const struct net_device_path *path;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	for (i = 0; i < stack->num_paths; i++) {
 | |
| ++		path = &stack->path[i];
 | |
| ++		switch (path->type) {
 | |
| ++		case DEV_PATH_ETHERNET:
 | |
| ++			info->indev = path->dev;
 | |
| ++			break;
 | |
| ++		case DEV_PATH_VLAN:
 | |
| ++		case DEV_PATH_BRIDGE:
 | |
| ++		default:
 | |
| ++			info->indev = NULL;
 | |
| ++			break;
 | |
| ++		}
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++static bool nft_flowtable_find_dev(const struct net_device *dev,
 | |
| ++				   struct nft_flowtable *ft)
 | |
| ++{
 | |
| ++	struct nft_hook *hook;
 | |
| ++	bool found = false;
 | |
| ++
 | |
| ++	list_for_each_entry_rcu(hook, &ft->hook_list, list) {
 | |
| ++		if (hook->ops.dev != dev)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		found = true;
 | |
| ++		break;
 | |
| ++	}
 | |
| ++
 | |
| ++	return found;
 | |
| ++}
 | |
| ++
 | |
| ++static void nft_dev_forward_path(struct nf_flow_route *route,
 | |
| ++				 const struct nf_conn *ct,
 | |
| ++				 enum ip_conntrack_dir dir,
 | |
| ++				 struct nft_flowtable *ft)
 | |
| ++{
 | |
| ++	const struct dst_entry *dst = route->tuple[dir].dst;
 | |
| ++	struct net_device_path_stack stack;
 | |
| ++	struct nft_forward_info info = {};
 | |
| ++
 | |
| ++	if (nft_dev_fill_forward_path(route, dst, ct, dir, &stack) >= 0)
 | |
| ++		nft_dev_path_info(&stack, &info);
 | |
| ++
 | |
| ++	if (!info.indev || !nft_flowtable_find_dev(info.indev, ft))
 | |
| ++		return;
 | |
| ++
 | |
| ++	route->tuple[!dir].in.ifindex = info.indev->ifindex;
 | |
| ++}
 | |
| ++
 | |
| + static int nft_flow_route(const struct nft_pktinfo *pkt,
 | |
| + 			  const struct nf_conn *ct,
 | |
| + 			  struct nf_flow_route *route,
 | |
| +-			  enum ip_conntrack_dir dir)
 | |
| ++			  enum ip_conntrack_dir dir,
 | |
| ++			  struct nft_flowtable *ft)
 | |
| + {
 | |
| + 	struct dst_entry *this_dst = skb_dst(pkt->skb);
 | |
| + 	struct dst_entry *other_dst = NULL;
 | |
| +@@ -63,6 +153,12 @@ static int nft_flow_route(const struct n
 | |
| + 	nft_default_forward_path(route, this_dst, dir);
 | |
| + 	nft_default_forward_path(route, other_dst, !dir);
 | |
| + 
 | |
| ++	if (route->tuple[dir].xmit_type	== FLOW_OFFLOAD_XMIT_NEIGH &&
 | |
| ++	    route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH) {
 | |
| ++		nft_dev_forward_path(route, ct, dir, ft);
 | |
| ++		nft_dev_forward_path(route, ct, !dir, ft);
 | |
| ++	}
 | |
| ++
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| +@@ -90,8 +186,8 @@ static void nft_flow_offload_eval(const
 | |
| + 	struct nft_flow_offload *priv = nft_expr_priv(expr);
 | |
| + 	struct nf_flowtable *flowtable = &priv->flowtable->data;
 | |
| + 	struct tcphdr _tcph, *tcph = NULL;
 | |
| ++	struct nf_flow_route route = {};
 | |
| + 	enum ip_conntrack_info ctinfo;
 | |
| +-	struct nf_flow_route route;
 | |
| + 	struct flow_offload *flow;
 | |
| + 	enum ip_conntrack_dir dir;
 | |
| + 	struct nf_conn *ct;
 | |
| +@@ -128,7 +224,7 @@ static void nft_flow_offload_eval(const
 | |
| + 		goto out;
 | |
| + 
 | |
| + 	dir = CTINFO2DIR(ctinfo);
 | |
| +-	if (nft_flow_route(pkt, ct, &route, dir) < 0)
 | |
| ++	if (nft_flow_route(pkt, ct, &route, dir, priv->flowtable) < 0)
 | |
| + 		goto err_flow_route;
 | |
| + 
 | |
| + 	flow = flow_offload_alloc(ct);
 | |
| diff --git a/target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch b/target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch
 | |
| new file mode 100644
 | |
| index 0000000000..ada14e6c7a
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-06-netfilter-flowtable-use-dev_fill_forward_path-to-obt.patch
 | |
| @@ -0,0 +1,344 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Thu, 4 Mar 2021 03:26:35 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: use dev_fill_forward_path() to
 | |
| + obtain egress device
 | |
| +
 | |
| +The egress device in the tuple is obtained from route. Use
 | |
| +dev_fill_forward_path() instead to provide the real egress device for
 | |
| +this flow whenever this is available.
 | |
| +
 | |
| +The new FLOW_OFFLOAD_XMIT_DIRECT type uses dev_queue_xmit() to transmit
 | |
| +ethernet frames. Cache the source and destination hardware address to
 | |
| +use dev_queue_xmit() to transfer packets.
 | |
| +
 | |
| +The FLOW_OFFLOAD_XMIT_DIRECT replaces FLOW_OFFLOAD_XMIT_NEIGH if
 | |
| +dev_fill_forward_path() finds a direct transmit path.
 | |
| +
 | |
| +In case of topology updates, if peer is moved to different bridge port,
 | |
| +the connection will time out, reconnect will result in a new entry with
 | |
| +the correct path. Snooping fdb updates would allow for cleaning up stale
 | |
| +flowtable entries.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -92,6 +92,7 @@ enum flow_offload_tuple_dir {
 | |
| + enum flow_offload_xmit_type {
 | |
| + 	FLOW_OFFLOAD_XMIT_NEIGH		= 0,
 | |
| + 	FLOW_OFFLOAD_XMIT_XFRM,
 | |
| ++	FLOW_OFFLOAD_XMIT_DIRECT,
 | |
| + };
 | |
| + 
 | |
| + struct flow_offload_tuple {
 | |
| +@@ -120,8 +121,14 @@ struct flow_offload_tuple {
 | |
| + 					xmit_type:2;
 | |
| + 
 | |
| + 	u16				mtu;
 | |
| +-
 | |
| +-	struct dst_entry		*dst_cache;
 | |
| ++	union {
 | |
| ++		struct dst_entry	*dst_cache;
 | |
| ++		struct {
 | |
| ++			u32		ifidx;
 | |
| ++			u8		h_source[ETH_ALEN];
 | |
| ++			u8		h_dest[ETH_ALEN];
 | |
| ++		} out;
 | |
| ++	};
 | |
| + };
 | |
| + 
 | |
| + struct flow_offload_tuple_rhash {
 | |
| +@@ -168,6 +175,11 @@ struct nf_flow_route {
 | |
| + 		struct {
 | |
| + 			u32			ifindex;
 | |
| + 		} in;
 | |
| ++		struct {
 | |
| ++			u32			ifindex;
 | |
| ++			u8			h_source[ETH_ALEN];
 | |
| ++			u8			h_dest[ETH_ALEN];
 | |
| ++		} out;
 | |
| + 		enum flow_offload_xmit_type	xmit_type;
 | |
| + 	} tuple[FLOW_OFFLOAD_DIR_MAX];
 | |
| + };
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -81,9 +81,6 @@ static int flow_offload_fill_route(struc
 | |
| + 	struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
 | |
| + 	struct dst_entry *dst = route->tuple[dir].dst;
 | |
| + 
 | |
| +-	if (!dst_hold_safe(route->tuple[dir].dst))
 | |
| +-		return -1;
 | |
| +-
 | |
| + 	switch (flow_tuple->l3proto) {
 | |
| + 	case NFPROTO_IPV4:
 | |
| + 		flow_tuple->mtu = ip_dst_mtu_maybe_forward(dst, true);
 | |
| +@@ -94,12 +91,36 @@ static int flow_offload_fill_route(struc
 | |
| + 	}
 | |
| + 
 | |
| + 	flow_tuple->iifidx = route->tuple[dir].in.ifindex;
 | |
| ++
 | |
| ++	switch (route->tuple[dir].xmit_type) {
 | |
| ++	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| ++		memcpy(flow_tuple->out.h_dest, route->tuple[dir].out.h_dest,
 | |
| ++		       ETH_ALEN);
 | |
| ++		memcpy(flow_tuple->out.h_source, route->tuple[dir].out.h_source,
 | |
| ++		       ETH_ALEN);
 | |
| ++		flow_tuple->out.ifidx = route->tuple[dir].out.ifindex;
 | |
| ++		break;
 | |
| ++	case FLOW_OFFLOAD_XMIT_XFRM:
 | |
| ++	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| ++		if (!dst_hold_safe(route->tuple[dir].dst))
 | |
| ++			return -1;
 | |
| ++
 | |
| ++		flow_tuple->dst_cache = dst;
 | |
| ++		break;
 | |
| ++	}
 | |
| + 	flow_tuple->xmit_type = route->tuple[dir].xmit_type;
 | |
| +-	flow_tuple->dst_cache = dst;
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| ++static void nft_flow_dst_release(struct flow_offload *flow,
 | |
| ++				 enum flow_offload_tuple_dir dir)
 | |
| ++{
 | |
| ++	if (flow->tuplehash[dir].tuple.xmit_type == FLOW_OFFLOAD_XMIT_NEIGH ||
 | |
| ++	    flow->tuplehash[dir].tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)
 | |
| ++		dst_release(flow->tuplehash[dir].tuple.dst_cache);
 | |
| ++}
 | |
| ++
 | |
| + int flow_offload_route_init(struct flow_offload *flow,
 | |
| + 			    const struct nf_flow_route *route)
 | |
| + {
 | |
| +@@ -118,7 +139,7 @@ int flow_offload_route_init(struct flow_
 | |
| + 	return 0;
 | |
| + 
 | |
| + err_route_reply:
 | |
| +-	dst_release(route->tuple[FLOW_OFFLOAD_DIR_ORIGINAL].dst);
 | |
| ++	nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL);
 | |
| + 
 | |
| + 	return err;
 | |
| + }
 | |
| +@@ -169,8 +190,8 @@ static void flow_offload_fixup_ct(struct
 | |
| + 
 | |
| + static void flow_offload_route_release(struct flow_offload *flow)
 | |
| + {
 | |
| +-	dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_cache);
 | |
| +-	dst_release(flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_cache);
 | |
| ++	nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL);
 | |
| ++	nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_REPLY);
 | |
| + }
 | |
| + 
 | |
| + void flow_offload_free(struct flow_offload *flow)
 | |
| +--- a/net/netfilter/nf_flow_table_ip.c
 | |
| ++++ b/net/netfilter/nf_flow_table_ip.c
 | |
| +@@ -248,6 +248,24 @@ static unsigned int nf_flow_xmit_xfrm(st
 | |
| + 	return NF_STOLEN;
 | |
| + }
 | |
| + 
 | |
| ++static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb,
 | |
| ++				       const struct flow_offload_tuple_rhash *tuplehash,
 | |
| ++				       unsigned short type)
 | |
| ++{
 | |
| ++	struct net_device *outdev;
 | |
| ++
 | |
| ++	outdev = dev_get_by_index_rcu(net, tuplehash->tuple.out.ifidx);
 | |
| ++	if (!outdev)
 | |
| ++		return NF_DROP;
 | |
| ++
 | |
| ++	skb->dev = outdev;
 | |
| ++	dev_hard_header(skb, skb->dev, type, tuplehash->tuple.out.h_dest,
 | |
| ++			tuplehash->tuple.out.h_source, skb->len);
 | |
| ++	dev_queue_xmit(skb);
 | |
| ++
 | |
| ++	return NF_STOLEN;
 | |
| ++}
 | |
| ++
 | |
| + unsigned int
 | |
| + nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 | |
| + 			const struct nf_hook_state *state)
 | |
| +@@ -262,6 +280,7 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 	unsigned int thoff;
 | |
| + 	struct iphdr *iph;
 | |
| + 	__be32 nexthop;
 | |
| ++	int ret;
 | |
| + 
 | |
| + 	if (skb->protocol != htons(ETH_P_IP))
 | |
| + 		return NF_ACCEPT;
 | |
| +@@ -303,22 +322,32 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 	if (flow_table->flags & NF_FLOWTABLE_COUNTER)
 | |
| + 		nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
 | |
| + 
 | |
| +-	rt = (struct rtable *)tuplehash->tuple.dst_cache;
 | |
| +-
 | |
| + 	if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
 | |
| ++		rt = (struct rtable *)tuplehash->tuple.dst_cache;
 | |
| + 		memset(skb->cb, 0, sizeof(struct inet_skb_parm));
 | |
| + 		IPCB(skb)->iif = skb->dev->ifindex;
 | |
| + 		IPCB(skb)->flags = IPSKB_FORWARDED;
 | |
| + 		return nf_flow_xmit_xfrm(skb, state, &rt->dst);
 | |
| + 	}
 | |
| + 
 | |
| +-	outdev = rt->dst.dev;
 | |
| +-	skb->dev = outdev;
 | |
| +-	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
 | |
| +-	skb_dst_set_noref(skb, &rt->dst);
 | |
| +-	neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb);
 | |
| ++	switch (tuplehash->tuple.xmit_type) {
 | |
| ++	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| ++		rt = (struct rtable *)tuplehash->tuple.dst_cache;
 | |
| ++		outdev = rt->dst.dev;
 | |
| ++		skb->dev = outdev;
 | |
| ++		nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
 | |
| ++		skb_dst_set_noref(skb, &rt->dst);
 | |
| ++		neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb);
 | |
| ++		ret = NF_STOLEN;
 | |
| ++		break;
 | |
| ++	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| ++		ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IP);
 | |
| ++		if (ret == NF_DROP)
 | |
| ++			flow_offload_teardown(flow);
 | |
| ++		break;
 | |
| ++	}
 | |
| + 
 | |
| +-	return NF_STOLEN;
 | |
| ++	return ret;
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(nf_flow_offload_ip_hook);
 | |
| + 
 | |
| +@@ -504,6 +533,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 	struct net_device *outdev;
 | |
| + 	struct ipv6hdr *ip6h;
 | |
| + 	struct rt6_info *rt;
 | |
| ++	int ret;
 | |
| + 
 | |
| + 	if (skb->protocol != htons(ETH_P_IPV6))
 | |
| + 		return NF_ACCEPT;
 | |
| +@@ -545,21 +575,31 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 	if (flow_table->flags & NF_FLOWTABLE_COUNTER)
 | |
| + 		nf_ct_acct_update(flow->ct, tuplehash->tuple.dir, skb->len);
 | |
| + 
 | |
| +-	rt = (struct rt6_info *)tuplehash->tuple.dst_cache;
 | |
| +-
 | |
| + 	if (unlikely(tuplehash->tuple.xmit_type == FLOW_OFFLOAD_XMIT_XFRM)) {
 | |
| ++		rt = (struct rt6_info *)tuplehash->tuple.dst_cache;
 | |
| + 		memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
 | |
| + 		IP6CB(skb)->iif = skb->dev->ifindex;
 | |
| + 		IP6CB(skb)->flags = IP6SKB_FORWARDED;
 | |
| + 		return nf_flow_xmit_xfrm(skb, state, &rt->dst);
 | |
| + 	}
 | |
| + 
 | |
| +-	outdev = rt->dst.dev;
 | |
| +-	skb->dev = outdev;
 | |
| +-	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
 | |
| +-	skb_dst_set_noref(skb, &rt->dst);
 | |
| +-	neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb);
 | |
| ++	switch (tuplehash->tuple.xmit_type) {
 | |
| ++	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| ++		rt = (struct rt6_info *)tuplehash->tuple.dst_cache;
 | |
| ++		outdev = rt->dst.dev;
 | |
| ++		skb->dev = outdev;
 | |
| ++		nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
 | |
| ++		skb_dst_set_noref(skb, &rt->dst);
 | |
| ++		neigh_xmit(NEIGH_ND_TABLE, outdev, nexthop, skb);
 | |
| ++		ret = NF_STOLEN;
 | |
| ++		break;
 | |
| ++	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| ++		ret = nf_flow_queue_xmit(state->net, skb, tuplehash, ETH_P_IPV6);
 | |
| ++		if (ret == NF_DROP)
 | |
| ++			flow_offload_teardown(flow);
 | |
| ++		break;
 | |
| ++	}
 | |
| + 
 | |
| +-	return NF_STOLEN;
 | |
| ++	return ret;
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(nf_flow_offload_ipv6_hook);
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -39,12 +39,11 @@ static void nft_default_forward_path(str
 | |
| + static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
 | |
| + 				     const struct dst_entry *dst_cache,
 | |
| + 				     const struct nf_conn *ct,
 | |
| +-				     enum ip_conntrack_dir dir,
 | |
| ++				     enum ip_conntrack_dir dir, u8 *ha,
 | |
| + 				     struct net_device_path_stack *stack)
 | |
| + {
 | |
| + 	const void *daddr = &ct->tuplehash[!dir].tuple.src.u3;
 | |
| + 	struct net_device *dev = dst_cache->dev;
 | |
| +-	unsigned char ha[ETH_ALEN];
 | |
| + 	struct neighbour *n;
 | |
| + 	u8 nud_state;
 | |
| + 
 | |
| +@@ -66,27 +65,43 @@ static int nft_dev_fill_forward_path(con
 | |
| + 
 | |
| + struct nft_forward_info {
 | |
| + 	const struct net_device *indev;
 | |
| ++	const struct net_device *outdev;
 | |
| ++	u8 h_source[ETH_ALEN];
 | |
| ++	u8 h_dest[ETH_ALEN];
 | |
| ++	enum flow_offload_xmit_type xmit_type;
 | |
| + };
 | |
| + 
 | |
| + static void nft_dev_path_info(const struct net_device_path_stack *stack,
 | |
| +-			      struct nft_forward_info *info)
 | |
| ++			      struct nft_forward_info *info,
 | |
| ++			      unsigned char *ha)
 | |
| + {
 | |
| + 	const struct net_device_path *path;
 | |
| + 	int i;
 | |
| + 
 | |
| ++	memcpy(info->h_dest, ha, ETH_ALEN);
 | |
| ++
 | |
| + 	for (i = 0; i < stack->num_paths; i++) {
 | |
| + 		path = &stack->path[i];
 | |
| + 		switch (path->type) {
 | |
| + 		case DEV_PATH_ETHERNET:
 | |
| + 			info->indev = path->dev;
 | |
| ++			if (is_zero_ether_addr(info->h_source))
 | |
| ++				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
 | |
| + 			break;
 | |
| +-		case DEV_PATH_VLAN:
 | |
| + 		case DEV_PATH_BRIDGE:
 | |
| ++			if (is_zero_ether_addr(info->h_source))
 | |
| ++				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
 | |
| ++
 | |
| ++			info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
 | |
| ++			break;
 | |
| ++		case DEV_PATH_VLAN:
 | |
| + 		default:
 | |
| + 			info->indev = NULL;
 | |
| + 			break;
 | |
| + 		}
 | |
| + 	}
 | |
| ++	if (!info->outdev)
 | |
| ++		info->outdev = info->indev;
 | |
| + }
 | |
| + 
 | |
| + static bool nft_flowtable_find_dev(const struct net_device *dev,
 | |
| +@@ -114,14 +129,22 @@ static void nft_dev_forward_path(struct
 | |
| + 	const struct dst_entry *dst = route->tuple[dir].dst;
 | |
| + 	struct net_device_path_stack stack;
 | |
| + 	struct nft_forward_info info = {};
 | |
| ++	unsigned char ha[ETH_ALEN];
 | |
| + 
 | |
| +-	if (nft_dev_fill_forward_path(route, dst, ct, dir, &stack) >= 0)
 | |
| +-		nft_dev_path_info(&stack, &info);
 | |
| ++	if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
 | |
| ++		nft_dev_path_info(&stack, &info, ha);
 | |
| + 
 | |
| + 	if (!info.indev || !nft_flowtable_find_dev(info.indev, ft))
 | |
| + 		return;
 | |
| + 
 | |
| + 	route->tuple[!dir].in.ifindex = info.indev->ifindex;
 | |
| ++
 | |
| ++	if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
 | |
| ++		memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
 | |
| ++		memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
 | |
| ++		route->tuple[dir].out.ifindex = info.outdev->ifindex;
 | |
| ++		route->tuple[dir].xmit_type = info.xmit_type;
 | |
| ++	}
 | |
| + }
 | |
| + 
 | |
| + static int nft_flow_route(const struct nft_pktinfo *pkt,
 | |
| diff --git a/target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch b/target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..fea1b59dc3
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-07-netfilter-flowtable-add-vlan-support.patch
 | |
| @@ -0,0 +1,391 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Fri, 20 Nov 2020 13:49:20 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: add vlan support
 | |
| +
 | |
| +Add the vlan id and protocol to the flow tuple to uniquely identify
 | |
| +flows from the receive path. For the transmit path, dev_hard_header() on
 | |
| +the vlan device push the headers. This patch includes support for two
 | |
| +VLAN headers (QinQ) from the ingress path.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -95,6 +95,8 @@ enum flow_offload_xmit_type {
 | |
| + 	FLOW_OFFLOAD_XMIT_DIRECT,
 | |
| + };
 | |
| + 
 | |
| ++#define NF_FLOW_TABLE_ENCAP_MAX		2
 | |
| ++
 | |
| + struct flow_offload_tuple {
 | |
| + 	union {
 | |
| + 		struct in_addr		src_v4;
 | |
| +@@ -113,13 +115,17 @@ struct flow_offload_tuple {
 | |
| + 
 | |
| + 	u8				l3proto;
 | |
| + 	u8				l4proto;
 | |
| ++	struct {
 | |
| ++		u16			id;
 | |
| ++		__be16			proto;
 | |
| ++	} encap[NF_FLOW_TABLE_ENCAP_MAX];
 | |
| + 
 | |
| + 	/* All members above are keys for lookups, see flow_offload_hash(). */
 | |
| + 	struct { }			__hash;
 | |
| + 
 | |
| +-	u8				dir:6,
 | |
| +-					xmit_type:2;
 | |
| +-
 | |
| ++	u8				dir:4,
 | |
| ++					xmit_type:2,
 | |
| ++					encap_num:2;
 | |
| + 	u16				mtu;
 | |
| + 	union {
 | |
| + 		struct dst_entry	*dst_cache;
 | |
| +@@ -174,6 +180,11 @@ struct nf_flow_route {
 | |
| + 		struct dst_entry		*dst;
 | |
| + 		struct {
 | |
| + 			u32			ifindex;
 | |
| ++			struct {
 | |
| ++				u16		id;
 | |
| ++				__be16		proto;
 | |
| ++			} encap[NF_FLOW_TABLE_ENCAP_MAX];
 | |
| ++			u8			num_encaps;
 | |
| + 		} in;
 | |
| + 		struct {
 | |
| + 			u32			ifindex;
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -80,6 +80,7 @@ static int flow_offload_fill_route(struc
 | |
| + {
 | |
| + 	struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
 | |
| + 	struct dst_entry *dst = route->tuple[dir].dst;
 | |
| ++	int i, j = 0;
 | |
| + 
 | |
| + 	switch (flow_tuple->l3proto) {
 | |
| + 	case NFPROTO_IPV4:
 | |
| +@@ -91,6 +92,12 @@ static int flow_offload_fill_route(struc
 | |
| + 	}
 | |
| + 
 | |
| + 	flow_tuple->iifidx = route->tuple[dir].in.ifindex;
 | |
| ++	for (i = route->tuple[dir].in.num_encaps - 1; i >= 0; i--) {
 | |
| ++		flow_tuple->encap[j].id = route->tuple[dir].in.encap[i].id;
 | |
| ++		flow_tuple->encap[j].proto = route->tuple[dir].in.encap[i].proto;
 | |
| ++		j++;
 | |
| ++	}
 | |
| ++	flow_tuple->encap_num = route->tuple[dir].in.num_encaps;
 | |
| + 
 | |
| + 	switch (route->tuple[dir].xmit_type) {
 | |
| + 	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| +--- a/net/netfilter/nf_flow_table_ip.c
 | |
| ++++ b/net/netfilter/nf_flow_table_ip.c
 | |
| +@@ -159,17 +159,38 @@ static bool ip_has_options(unsigned int
 | |
| + 	return thoff != sizeof(struct iphdr);
 | |
| + }
 | |
| + 
 | |
| ++static void nf_flow_tuple_encap(struct sk_buff *skb,
 | |
| ++				struct flow_offload_tuple *tuple)
 | |
| ++{
 | |
| ++	int i = 0;
 | |
| ++
 | |
| ++	if (skb_vlan_tag_present(skb)) {
 | |
| ++		tuple->encap[i].id = skb_vlan_tag_get(skb);
 | |
| ++		tuple->encap[i].proto = skb->vlan_proto;
 | |
| ++		i++;
 | |
| ++	}
 | |
| ++	if (skb->protocol == htons(ETH_P_8021Q)) {
 | |
| ++		struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb_mac_header(skb);
 | |
| ++
 | |
| ++		tuple->encap[i].id = ntohs(veth->h_vlan_TCI);
 | |
| ++		tuple->encap[i].proto = skb->protocol;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| + static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
 | |
| + 			    struct flow_offload_tuple *tuple)
 | |
| + {
 | |
| +-	unsigned int thoff, hdrsize;
 | |
| ++	unsigned int thoff, hdrsize, offset = 0;
 | |
| + 	struct flow_ports *ports;
 | |
| + 	struct iphdr *iph;
 | |
| + 
 | |
| +-	if (!pskb_may_pull(skb, sizeof(*iph)))
 | |
| ++	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| ++		offset += VLAN_HLEN;
 | |
| ++
 | |
| ++	if (!pskb_may_pull(skb, sizeof(*iph) + offset))
 | |
| + 		return -1;
 | |
| + 
 | |
| +-	iph = ip_hdr(skb);
 | |
| ++	iph = (struct iphdr *)(skb_network_header(skb) + offset);
 | |
| + 	thoff = iph->ihl * 4;
 | |
| + 
 | |
| + 	if (ip_is_fragment(iph) ||
 | |
| +@@ -191,11 +212,11 @@ static int nf_flow_tuple_ip(struct sk_bu
 | |
| + 		return -1;
 | |
| + 
 | |
| + 	thoff = iph->ihl * 4;
 | |
| +-	if (!pskb_may_pull(skb, thoff + hdrsize))
 | |
| ++	if (!pskb_may_pull(skb, thoff + hdrsize + offset))
 | |
| + 		return -1;
 | |
| + 
 | |
| +-	iph = ip_hdr(skb);
 | |
| +-	ports = (struct flow_ports *)(skb_network_header(skb) + thoff);
 | |
| ++	iph = (struct iphdr *)(skb_network_header(skb) + offset);
 | |
| ++	ports = (struct flow_ports *)(skb_network_header(skb) + thoff + offset);
 | |
| + 
 | |
| + 	tuple->src_v4.s_addr	= iph->saddr;
 | |
| + 	tuple->dst_v4.s_addr	= iph->daddr;
 | |
| +@@ -204,6 +225,7 @@ static int nf_flow_tuple_ip(struct sk_bu
 | |
| + 	tuple->l3proto		= AF_INET;
 | |
| + 	tuple->l4proto		= iph->protocol;
 | |
| + 	tuple->iifidx		= dev->ifindex;
 | |
| ++	nf_flow_tuple_encap(skb, tuple);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -248,6 +270,40 @@ static unsigned int nf_flow_xmit_xfrm(st
 | |
| + 	return NF_STOLEN;
 | |
| + }
 | |
| + 
 | |
| ++static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto)
 | |
| ++{
 | |
| ++	if (skb->protocol == htons(ETH_P_8021Q)) {
 | |
| ++		struct vlan_ethhdr *veth;
 | |
| ++
 | |
| ++		veth = (struct vlan_ethhdr *)skb_mac_header(skb);
 | |
| ++		if (veth->h_vlan_encapsulated_proto == proto)
 | |
| ++			return true;
 | |
| ++	}
 | |
| ++
 | |
| ++	return false;
 | |
| ++}
 | |
| ++
 | |
| ++static void nf_flow_encap_pop(struct sk_buff *skb,
 | |
| ++			      struct flow_offload_tuple_rhash *tuplehash)
 | |
| ++{
 | |
| ++	struct vlan_hdr *vlan_hdr;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	for (i = 0; i < tuplehash->tuple.encap_num; i++) {
 | |
| ++		if (skb_vlan_tag_present(skb)) {
 | |
| ++			__vlan_hwaccel_clear_tag(skb);
 | |
| ++			continue;
 | |
| ++		}
 | |
| ++		if (skb->protocol == htons(ETH_P_8021Q)) {
 | |
| ++			vlan_hdr = (struct vlan_hdr *)skb->data;
 | |
| ++			__skb_pull(skb, VLAN_HLEN);
 | |
| ++			vlan_set_encap_proto(skb, vlan_hdr);
 | |
| ++			skb_reset_network_header(skb);
 | |
| ++			break;
 | |
| ++		}
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| + static unsigned int nf_flow_queue_xmit(struct net *net, struct sk_buff *skb,
 | |
| + 				       const struct flow_offload_tuple_rhash *tuplehash,
 | |
| + 				       unsigned short type)
 | |
| +@@ -276,13 +332,15 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 	enum flow_offload_tuple_dir dir;
 | |
| + 	struct flow_offload *flow;
 | |
| + 	struct net_device *outdev;
 | |
| ++	unsigned int thoff, mtu;
 | |
| + 	struct rtable *rt;
 | |
| +-	unsigned int thoff;
 | |
| + 	struct iphdr *iph;
 | |
| + 	__be32 nexthop;
 | |
| ++	u32 offset = 0;
 | |
| + 	int ret;
 | |
| + 
 | |
| +-	if (skb->protocol != htons(ETH_P_IP))
 | |
| ++	if (skb->protocol != htons(ETH_P_IP) &&
 | |
| ++	    !nf_flow_skb_encap_protocol(skb, htons(ETH_P_IP)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| + 	if (nf_flow_tuple_ip(skb, state->in, &tuple) < 0)
 | |
| +@@ -295,14 +353,19 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 	dir = tuplehash->tuple.dir;
 | |
| + 	flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
 | |
| + 
 | |
| +-	if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
 | |
| ++	mtu = flow->tuplehash[dir].tuple.mtu + offset;
 | |
| ++	if (unlikely(nf_flow_exceeds_mtu(skb, mtu)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| +-	if (skb_try_make_writable(skb, sizeof(*iph)))
 | |
| ++	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| ++		offset += VLAN_HLEN;
 | |
| ++
 | |
| ++	if (skb_try_make_writable(skb, sizeof(*iph) + offset))
 | |
| + 		return NF_DROP;
 | |
| + 
 | |
| +-	thoff = ip_hdr(skb)->ihl * 4;
 | |
| +-	if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff))
 | |
| ++	iph = (struct iphdr *)(skb_network_header(skb) + offset);
 | |
| ++	thoff = (iph->ihl * 4) + offset;
 | |
| ++	if (nf_flow_state_check(flow, iph->protocol, skb, thoff))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| + 	flow_offload_refresh(flow_table, flow);
 | |
| +@@ -312,6 +375,9 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 		return NF_ACCEPT;
 | |
| + 	}
 | |
| + 
 | |
| ++	nf_flow_encap_pop(skb, tuplehash);
 | |
| ++	thoff -= offset;
 | |
| ++
 | |
| + 	if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0)
 | |
| + 		return NF_DROP;
 | |
| + 
 | |
| +@@ -479,14 +545,17 @@ static int nf_flow_nat_ipv6(const struct
 | |
| + static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev,
 | |
| + 			      struct flow_offload_tuple *tuple)
 | |
| + {
 | |
| +-	unsigned int thoff, hdrsize;
 | |
| ++	unsigned int thoff, hdrsize, offset = 0;
 | |
| + 	struct flow_ports *ports;
 | |
| + 	struct ipv6hdr *ip6h;
 | |
| + 
 | |
| +-	if (!pskb_may_pull(skb, sizeof(*ip6h)))
 | |
| ++	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| ++		offset += VLAN_HLEN;
 | |
| ++
 | |
| ++	if (!pskb_may_pull(skb, sizeof(*ip6h) + offset))
 | |
| + 		return -1;
 | |
| + 
 | |
| +-	ip6h = ipv6_hdr(skb);
 | |
| ++	ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset);
 | |
| + 
 | |
| + 	switch (ip6h->nexthdr) {
 | |
| + 	case IPPROTO_TCP:
 | |
| +@@ -503,11 +572,11 @@ static int nf_flow_tuple_ipv6(struct sk_
 | |
| + 		return -1;
 | |
| + 
 | |
| + 	thoff = sizeof(*ip6h);
 | |
| +-	if (!pskb_may_pull(skb, thoff + hdrsize))
 | |
| ++	if (!pskb_may_pull(skb, thoff + hdrsize + offset))
 | |
| + 		return -1;
 | |
| + 
 | |
| +-	ip6h = ipv6_hdr(skb);
 | |
| +-	ports = (struct flow_ports *)(skb_network_header(skb) + thoff);
 | |
| ++	ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset);
 | |
| ++	ports = (struct flow_ports *)(skb_network_header(skb) + thoff + offset);
 | |
| + 
 | |
| + 	tuple->src_v6		= ip6h->saddr;
 | |
| + 	tuple->dst_v6		= ip6h->daddr;
 | |
| +@@ -516,6 +585,7 @@ static int nf_flow_tuple_ipv6(struct sk_
 | |
| + 	tuple->l3proto		= AF_INET6;
 | |
| + 	tuple->l4proto		= ip6h->nexthdr;
 | |
| + 	tuple->iifidx		= dev->ifindex;
 | |
| ++	nf_flow_tuple_encap(skb, tuple);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -533,9 +603,12 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 	struct net_device *outdev;
 | |
| + 	struct ipv6hdr *ip6h;
 | |
| + 	struct rt6_info *rt;
 | |
| ++	unsigned int mtu;
 | |
| ++	u32 offset = 0;
 | |
| + 	int ret;
 | |
| + 
 | |
| +-	if (skb->protocol != htons(ETH_P_IPV6))
 | |
| ++	if (skb->protocol != htons(ETH_P_IPV6) &&
 | |
| ++	    !nf_flow_skb_encap_protocol(skb, htons(ETH_P_IPV6)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| + 	if (nf_flow_tuple_ipv6(skb, state->in, &tuple) < 0)
 | |
| +@@ -548,11 +621,15 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 	dir = tuplehash->tuple.dir;
 | |
| + 	flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
 | |
| + 
 | |
| +-	if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)))
 | |
| ++	mtu = flow->tuplehash[dir].tuple.mtu + offset;
 | |
| ++	if (unlikely(nf_flow_exceeds_mtu(skb, mtu)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| +-	if (nf_flow_state_check(flow, ipv6_hdr(skb)->nexthdr, skb,
 | |
| +-				sizeof(*ip6h)))
 | |
| ++	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| ++		offset += VLAN_HLEN;
 | |
| ++
 | |
| ++	ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset);
 | |
| ++	if (nf_flow_state_check(flow, ip6h->nexthdr, skb, sizeof(*ip6h)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| + 	flow_offload_refresh(flow_table, flow);
 | |
| +@@ -562,6 +639,8 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 		return NF_ACCEPT;
 | |
| + 	}
 | |
| + 
 | |
| ++	nf_flow_encap_pop(skb, tuplehash);
 | |
| ++
 | |
| + 	if (skb_try_make_writable(skb, sizeof(*ip6h)))
 | |
| + 		return NF_DROP;
 | |
| + 
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -66,6 +66,11 @@ static int nft_dev_fill_forward_path(con
 | |
| + struct nft_forward_info {
 | |
| + 	const struct net_device *indev;
 | |
| + 	const struct net_device *outdev;
 | |
| ++	struct id {
 | |
| ++		__u16	id;
 | |
| ++		__be16	proto;
 | |
| ++	} encap[NF_FLOW_TABLE_ENCAP_MAX];
 | |
| ++	u8 num_encaps;
 | |
| + 	u8 h_source[ETH_ALEN];
 | |
| + 	u8 h_dest[ETH_ALEN];
 | |
| + 	enum flow_offload_xmit_type xmit_type;
 | |
| +@@ -84,9 +89,23 @@ static void nft_dev_path_info(const stru
 | |
| + 		path = &stack->path[i];
 | |
| + 		switch (path->type) {
 | |
| + 		case DEV_PATH_ETHERNET:
 | |
| ++		case DEV_PATH_VLAN:
 | |
| + 			info->indev = path->dev;
 | |
| + 			if (is_zero_ether_addr(info->h_source))
 | |
| + 				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
 | |
| ++
 | |
| ++			if (path->type == DEV_PATH_ETHERNET)
 | |
| ++				break;
 | |
| ++
 | |
| ++			/* DEV_PATH_VLAN */
 | |
| ++			if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
 | |
| ++				info->indev = NULL;
 | |
| ++				break;
 | |
| ++			}
 | |
| ++			info->outdev = path->dev;
 | |
| ++			info->encap[info->num_encaps].id = path->encap.id;
 | |
| ++			info->encap[info->num_encaps].proto = path->encap.proto;
 | |
| ++			info->num_encaps++;
 | |
| + 			break;
 | |
| + 		case DEV_PATH_BRIDGE:
 | |
| + 			if (is_zero_ether_addr(info->h_source))
 | |
| +@@ -94,7 +113,6 @@ static void nft_dev_path_info(const stru
 | |
| + 
 | |
| + 			info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
 | |
| + 			break;
 | |
| +-		case DEV_PATH_VLAN:
 | |
| + 		default:
 | |
| + 			info->indev = NULL;
 | |
| + 			break;
 | |
| +@@ -130,6 +148,7 @@ static void nft_dev_forward_path(struct
 | |
| + 	struct net_device_path_stack stack;
 | |
| + 	struct nft_forward_info info = {};
 | |
| + 	unsigned char ha[ETH_ALEN];
 | |
| ++	int i;
 | |
| + 
 | |
| + 	if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
 | |
| + 		nft_dev_path_info(&stack, &info, ha);
 | |
| +@@ -138,6 +157,11 @@ static void nft_dev_forward_path(struct
 | |
| + 		return;
 | |
| + 
 | |
| + 	route->tuple[!dir].in.ifindex = info.indev->ifindex;
 | |
| ++	for (i = 0; i < info.num_encaps; i++) {
 | |
| ++		route->tuple[!dir].in.encap[i].id = info.encap[i].id;
 | |
| ++		route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
 | |
| ++	}
 | |
| ++	route->tuple[!dir].in.num_encaps = info.num_encaps;
 | |
| + 
 | |
| + 	if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
 | |
| + 		memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
 | |
| diff --git a/target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch b/target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch
 | |
| new file mode 100644
 | |
| index 0000000000..1ee015c6aa
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-08-selftests-netfilter-flowtable-bridge-and-VLAN-suppor.patch
 | |
| @@ -0,0 +1,107 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Fri, 20 Nov 2020 13:49:21 +0100
 | |
| +Subject: [PATCH] selftests: netfilter: flowtable bridge and VLAN support
 | |
| +
 | |
| +This patch adds two new tests to cover bridge and VLAN support:
 | |
| +
 | |
| +- Add a bridge device to the Router1 (nsr1) container and attach the
 | |
| +  veth0 device to the bridge. Set the IP address to the bridge device
 | |
| +  to exercise the bridge forwarding path.
 | |
| +
 | |
| +- Add VLAN encapsulation between to the bridge device in the Router1 and
 | |
| +  one of the sender containers (ns1).
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/tools/testing/selftests/netfilter/nft_flowtable.sh
 | |
| ++++ b/tools/testing/selftests/netfilter/nft_flowtable.sh
 | |
| +@@ -371,6 +371,88 @@ else
 | |
| + 	ip netns exec nsr1 nft list ruleset
 | |
| + fi
 | |
| + 
 | |
| ++# Another test:
 | |
| ++# Add bridge interface br0 to Router1, with NAT enabled.
 | |
| ++ip -net nsr1 link add name br0 type bridge
 | |
| ++ip -net nsr1 addr flush dev veth0
 | |
| ++ip -net nsr1 link set up dev veth0
 | |
| ++ip -net nsr1 link set veth0 master br0
 | |
| ++ip -net nsr1 addr add 10.0.1.1/24 dev br0
 | |
| ++ip -net nsr1 addr add dead:1::1/64 dev br0
 | |
| ++ip -net nsr1 link set up dev br0
 | |
| ++
 | |
| ++ip netns exec nsr1 sysctl net.ipv4.conf.br0.forwarding=1 > /dev/null
 | |
| ++
 | |
| ++# br0 with NAT enabled.
 | |
| ++ip netns exec nsr1 nft -f - <<EOF
 | |
| ++flush table ip nat
 | |
| ++table ip nat {
 | |
| ++   chain prerouting {
 | |
| ++      type nat hook prerouting priority 0; policy accept;
 | |
| ++      meta iif "br0" ip daddr 10.6.6.6 tcp dport 1666 counter dnat ip to 10.0.2.99:12345
 | |
| ++   }
 | |
| ++
 | |
| ++   chain postrouting {
 | |
| ++      type nat hook postrouting priority 0; policy accept;
 | |
| ++      meta oifname "veth1" counter masquerade
 | |
| ++   }
 | |
| ++}
 | |
| ++EOF
 | |
| ++
 | |
| ++if test_tcp_forwarding_nat ns1 ns2; then
 | |
| ++	echo "PASS: flow offloaded for ns1/ns2 with bridge NAT"
 | |
| ++else
 | |
| ++	echo "FAIL: flow offload for ns1/ns2 with bridge NAT" 1>&2
 | |
| ++	ip netns exec nsr1 nft list ruleset
 | |
| ++	ret=1
 | |
| ++fi
 | |
| ++
 | |
| ++# Another test:
 | |
| ++# Add bridge interface br0 to Router1, with NAT and VLAN.
 | |
| ++ip -net nsr1 link set veth0 nomaster
 | |
| ++ip -net nsr1 link set down dev veth0
 | |
| ++ip -net nsr1 link add link veth0 name veth0.10 type vlan id 10
 | |
| ++ip -net nsr1 link set up dev veth0
 | |
| ++ip -net nsr1 link set up dev veth0.10
 | |
| ++ip -net nsr1 link set veth0.10 master br0
 | |
| ++
 | |
| ++ip -net ns1 addr flush dev eth0
 | |
| ++ip -net ns1 link add link eth0 name eth0.10 type vlan id 10
 | |
| ++ip -net ns1 link set eth0 up
 | |
| ++ip -net ns1 link set eth0.10 up
 | |
| ++ip -net ns1 addr add 10.0.1.99/24 dev eth0.10
 | |
| ++ip -net ns1 route add default via 10.0.1.1
 | |
| ++ip -net ns1 addr add dead:1::99/64 dev eth0.10
 | |
| ++
 | |
| ++if test_tcp_forwarding_nat ns1 ns2; then
 | |
| ++	echo "PASS: flow offloaded for ns1/ns2 with bridge NAT and VLAN"
 | |
| ++else
 | |
| ++	echo "FAIL: flow offload for ns1/ns2 with bridge NAT and VLAN" 1>&2
 | |
| ++	ip netns exec nsr1 nft list ruleset
 | |
| ++	ret=1
 | |
| ++fi
 | |
| ++
 | |
| ++# restore test topology (remove bridge and VLAN)
 | |
| ++ip -net nsr1 link set veth0 nomaster
 | |
| ++ip -net nsr1 link set veth0 down
 | |
| ++ip -net nsr1 link set veth0.10 down
 | |
| ++ip -net nsr1 link delete veth0.10 type vlan
 | |
| ++ip -net nsr1 link delete br0 type bridge
 | |
| ++ip -net ns1 addr flush dev eth0.10
 | |
| ++ip -net ns1 link set eth0.10 down
 | |
| ++ip -net ns1 link set eth0 down
 | |
| ++ip -net ns1 link delete eth0.10 type vlan
 | |
| ++
 | |
| ++# restore address in ns1 and nsr1
 | |
| ++ip -net ns1 link set eth0 up
 | |
| ++ip -net ns1 addr add 10.0.1.99/24 dev eth0
 | |
| ++ip -net ns1 route add default via 10.0.1.1
 | |
| ++ip -net ns1 addr add dead:1::99/64 dev eth0
 | |
| ++ip -net ns1 route add default via dead:1::1
 | |
| ++ip -net nsr1 addr add 10.0.1.1/24 dev veth0
 | |
| ++ip -net nsr1 addr add dead:1::1/64 dev veth0
 | |
| ++ip -net nsr1 link set up dev veth0
 | |
| ++
 | |
| + KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1)
 | |
| + KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1)
 | |
| + SPI1=$RANDOM
 | |
| diff --git a/target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch b/target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch
 | |
| new file mode 100644
 | |
| index 0000000000..8f8d58b299
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-09-net-bridge-resolve-VLAN-tag-actions-in-forwarding-pa.patch
 | |
| @@ -0,0 +1,207 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Mon, 7 Dec 2020 20:31:45 +0100
 | |
| +Subject: [PATCH] net: bridge: resolve VLAN tag actions in forwarding
 | |
| + path for bridge devices
 | |
| +
 | |
| +Depending on the VLAN settings of the bridge and the port, the bridge can
 | |
| +either add or remove a tag. When vlan filtering is enabled, the fdb lookup
 | |
| +also needs to know the VLAN tag/proto for the destination address
 | |
| +To provide this, keep track of the stack of VLAN tags for the path in the
 | |
| +lookup context
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -841,10 +841,20 @@ struct net_device_path {
 | |
| + 			u16		id;
 | |
| + 			__be16		proto;
 | |
| + 		} encap;
 | |
| ++		struct {
 | |
| ++			enum {
 | |
| ++				DEV_PATH_BR_VLAN_KEEP,
 | |
| ++				DEV_PATH_BR_VLAN_TAG,
 | |
| ++				DEV_PATH_BR_VLAN_UNTAG,
 | |
| ++			}		vlan_mode;
 | |
| ++			u16		vlan_id;
 | |
| ++			__be16		vlan_proto;
 | |
| ++		} bridge;
 | |
| + 	};
 | |
| + };
 | |
| + 
 | |
| + #define NET_DEVICE_PATH_STACK_MAX	5
 | |
| ++#define NET_DEVICE_PATH_VLAN_MAX	2
 | |
| + 
 | |
| + struct net_device_path_stack {
 | |
| + 	int			num_paths;
 | |
| +@@ -854,6 +864,12 @@ struct net_device_path_stack {
 | |
| + struct net_device_path_ctx {
 | |
| + 	const struct net_device *dev;
 | |
| + 	const u8		*daddr;
 | |
| ++
 | |
| ++	int			num_vlans;
 | |
| ++	struct {
 | |
| ++		u16		id;
 | |
| ++		__be16		proto;
 | |
| ++	} vlan[NET_DEVICE_PATH_VLAN_MAX];
 | |
| + };
 | |
| + 
 | |
| + enum tc_setup_type {
 | |
| +--- a/net/8021q/vlan_dev.c
 | |
| ++++ b/net/8021q/vlan_dev.c
 | |
| +@@ -777,6 +777,12 @@ static int vlan_dev_fill_forward_path(st
 | |
| + 	path->encap.proto = vlan->vlan_proto;
 | |
| + 	path->dev = ctx->dev;
 | |
| + 	ctx->dev = vlan->real_dev;
 | |
| ++	if (ctx->num_vlans >= ARRAY_SIZE(ctx->vlan))
 | |
| ++		return -ENOSPC;
 | |
| ++
 | |
| ++	ctx->vlan[ctx->num_vlans].id = vlan->vlan_id;
 | |
| ++	ctx->vlan[ctx->num_vlans].proto = vlan->vlan_proto;
 | |
| ++	ctx->num_vlans++;
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +--- a/net/bridge/br_device.c
 | |
| ++++ b/net/bridge/br_device.c
 | |
| +@@ -409,7 +409,10 @@ static int br_fill_forward_path(struct n
 | |
| + 		return -1;
 | |
| + 
 | |
| + 	br = netdev_priv(ctx->dev);
 | |
| +-	f = br_fdb_find_rcu(br, ctx->daddr, 0);
 | |
| ++
 | |
| ++	br_vlan_fill_forward_path_pvid(br, ctx, path);
 | |
| ++
 | |
| ++	f = br_fdb_find_rcu(br, ctx->daddr, path->bridge.vlan_id);
 | |
| + 	if (!f || !f->dst)
 | |
| + 		return -1;
 | |
| + 
 | |
| +@@ -417,10 +420,28 @@ static int br_fill_forward_path(struct n
 | |
| + 	if (!dst)
 | |
| + 		return -1;
 | |
| + 
 | |
| ++	if (br_vlan_fill_forward_path_mode(br, dst, path))
 | |
| ++		return -1;
 | |
| ++
 | |
| + 	path->type = DEV_PATH_BRIDGE;
 | |
| + 	path->dev = dst->br->dev;
 | |
| + 	ctx->dev = dst->dev;
 | |
| + 
 | |
| ++	switch (path->bridge.vlan_mode) {
 | |
| ++	case DEV_PATH_BR_VLAN_TAG:
 | |
| ++		if (ctx->num_vlans >= ARRAY_SIZE(ctx->vlan))
 | |
| ++			return -ENOSPC;
 | |
| ++		ctx->vlan[ctx->num_vlans].id = path->bridge.vlan_id;
 | |
| ++		ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto;
 | |
| ++		ctx->num_vlans++;
 | |
| ++		break;
 | |
| ++	case DEV_PATH_BR_VLAN_UNTAG:
 | |
| ++		ctx->num_vlans--;
 | |
| ++		break;
 | |
| ++	case DEV_PATH_BR_VLAN_KEEP:
 | |
| ++		break;
 | |
| ++	}
 | |
| ++
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| +--- a/net/bridge/br_private.h
 | |
| ++++ b/net/bridge/br_private.h
 | |
| +@@ -1095,6 +1095,13 @@ void br_vlan_notify(const struct net_bri
 | |
| + bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
 | |
| + 			     const struct net_bridge_vlan *range_end);
 | |
| + 
 | |
| ++void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
 | |
| ++				    struct net_device_path_ctx *ctx,
 | |
| ++				    struct net_device_path *path);
 | |
| ++int br_vlan_fill_forward_path_mode(struct net_bridge *br,
 | |
| ++				   struct net_bridge_port *dst,
 | |
| ++				   struct net_device_path *path);
 | |
| ++
 | |
| + static inline struct net_bridge_vlan_group *br_vlan_group(
 | |
| + 					const struct net_bridge *br)
 | |
| + {
 | |
| +@@ -1252,6 +1259,19 @@ static inline int nbp_get_num_vlan_infos
 | |
| + {
 | |
| + 	return 0;
 | |
| + }
 | |
| ++
 | |
| ++static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
 | |
| ++						  struct net_device_path_ctx *ctx,
 | |
| ++						  struct net_device_path *path)
 | |
| ++{
 | |
| ++}
 | |
| ++
 | |
| ++static inline int br_vlan_fill_forward_path_mode(struct net_bridge *br,
 | |
| ++						 struct net_bridge_port *dst,
 | |
| ++						 struct net_device_path *path)
 | |
| ++{
 | |
| ++	return 0;
 | |
| ++}
 | |
| + 
 | |
| + static inline struct net_bridge_vlan_group *br_vlan_group(
 | |
| + 					const struct net_bridge *br)
 | |
| +--- a/net/bridge/br_vlan.c
 | |
| ++++ b/net/bridge/br_vlan.c
 | |
| +@@ -1327,6 +1327,59 @@ int br_vlan_get_pvid_rcu(const struct ne
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu);
 | |
| + 
 | |
| ++void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
 | |
| ++				    struct net_device_path_ctx *ctx,
 | |
| ++				    struct net_device_path *path)
 | |
| ++{
 | |
| ++	struct net_bridge_vlan_group *vg;
 | |
| ++	int idx = ctx->num_vlans - 1;
 | |
| ++	u16 vid;
 | |
| ++
 | |
| ++	path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
 | |
| ++
 | |
| ++	if (!br_opt_get(br, BROPT_VLAN_ENABLED))
 | |
| ++		return;
 | |
| ++
 | |
| ++	vg = br_vlan_group(br);
 | |
| ++
 | |
| ++	if (idx >= 0 &&
 | |
| ++	    ctx->vlan[idx].proto == br->vlan_proto) {
 | |
| ++		vid = ctx->vlan[idx].id;
 | |
| ++	} else {
 | |
| ++		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_TAG;
 | |
| ++		vid = br_get_pvid(vg);
 | |
| ++	}
 | |
| ++
 | |
| ++	path->bridge.vlan_id = vid;
 | |
| ++	path->bridge.vlan_proto = br->vlan_proto;
 | |
| ++}
 | |
| ++
 | |
| ++int br_vlan_fill_forward_path_mode(struct net_bridge *br,
 | |
| ++				   struct net_bridge_port *dst,
 | |
| ++				   struct net_device_path *path)
 | |
| ++{
 | |
| ++	struct net_bridge_vlan_group *vg;
 | |
| ++	struct net_bridge_vlan *v;
 | |
| ++
 | |
| ++	if (!br_opt_get(br, BROPT_VLAN_ENABLED))
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	vg = nbp_vlan_group_rcu(dst);
 | |
| ++	v = br_vlan_find(vg, path->bridge.vlan_id);
 | |
| ++	if (!v || !br_vlan_should_use(v))
 | |
| ++		return -EINVAL;
 | |
| ++
 | |
| ++	if (!(v->flags & BRIDGE_VLAN_INFO_UNTAGGED))
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
 | |
| ++		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
 | |
| ++	else
 | |
| ++		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + int br_vlan_get_info(const struct net_device *dev, u16 vid,
 | |
| + 		     struct bridge_vlan_info *p_vinfo)
 | |
| + {
 | |
| diff --git a/target/linux/generic/pending-5.10/640-10-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch b/target/linux/generic/pending-5.10/640-10-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch
 | |
| new file mode 100644
 | |
| index 0000000000..86fd6bf77b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-10-netfilter-nft_flow_offload-add-bridge-vlan-filtering.patch
 | |
| @@ -0,0 +1,31 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Sun, 24 Jan 2021 18:01:34 +0100
 | |
| +Subject: [PATCH] netfilter: nft_flow_offload: add bridge vlan filtering
 | |
| + support
 | |
| +
 | |
| +Add the vlan tag based when PVID is set on.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -111,6 +111,18 @@ static void nft_dev_path_info(const stru
 | |
| + 			if (is_zero_ether_addr(info->h_source))
 | |
| + 				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
 | |
| + 
 | |
| ++			switch (path->bridge.vlan_mode) {
 | |
| ++			case DEV_PATH_BR_VLAN_TAG:
 | |
| ++				info->encap[info->num_encaps].id = path->bridge.vlan_id;
 | |
| ++				info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
 | |
| ++				info->num_encaps++;
 | |
| ++				break;
 | |
| ++			case DEV_PATH_BR_VLAN_UNTAG:
 | |
| ++				info->num_encaps--;
 | |
| ++				break;
 | |
| ++			case DEV_PATH_BR_VLAN_KEEP:
 | |
| ++				break;
 | |
| ++			}
 | |
| + 			info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
 | |
| + 			break;
 | |
| + 		default:
 | |
| diff --git a/target/linux/generic/pending-5.10/640-11-net-ppp-resolve-forwarding-path-for-bridge-pppoe-dev.patch b/target/linux/generic/pending-5.10/640-11-net-ppp-resolve-forwarding-path-for-bridge-pppoe-dev.patch
 | |
| new file mode 100644
 | |
| index 0000000000..88c89b27a0
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-11-net-ppp-resolve-forwarding-path-for-bridge-pppoe-dev.patch
 | |
| @@ -0,0 +1,100 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Tue, 2 Mar 2021 21:45:16 +0100
 | |
| +Subject: [PATCH] net: ppp: resolve forwarding path for bridge pppoe
 | |
| + devices
 | |
| +
 | |
| +Pass on the PPPoE session ID and the real device.
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ppp/ppp_generic.c
 | |
| ++++ b/drivers/net/ppp/ppp_generic.c
 | |
| +@@ -1450,12 +1450,34 @@ static void ppp_dev_priv_destructor(stru
 | |
| + 		ppp_destroy_interface(ppp);
 | |
| + }
 | |
| + 
 | |
| ++static int ppp_fill_forward_path(struct net_device_path_ctx *ctx,
 | |
| ++				 struct net_device_path *path)
 | |
| ++{
 | |
| ++	struct ppp *ppp = netdev_priv(path->dev);
 | |
| ++	struct ppp_channel *chan;
 | |
| ++	struct channel *pch;
 | |
| ++
 | |
| ++	if (ppp->flags & SC_MULTILINK)
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	if (list_empty(&ppp->channels))
 | |
| ++		return -ENODEV;
 | |
| ++
 | |
| ++	pch = list_first_entry(&ppp->channels, struct channel, clist);
 | |
| ++	chan = pch->chan;
 | |
| ++	if (!chan->ops->fill_forward_path)
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	return chan->ops->fill_forward_path(ctx, path, chan);
 | |
| ++}
 | |
| ++
 | |
| + static const struct net_device_ops ppp_netdev_ops = {
 | |
| + 	.ndo_init	 = ppp_dev_init,
 | |
| + 	.ndo_uninit      = ppp_dev_uninit,
 | |
| + 	.ndo_start_xmit  = ppp_start_xmit,
 | |
| + 	.ndo_do_ioctl    = ppp_net_ioctl,
 | |
| + 	.ndo_get_stats64 = ppp_get_stats64,
 | |
| ++	.ndo_fill_forward_path = ppp_fill_forward_path,
 | |
| + };
 | |
| + 
 | |
| + static struct device_type ppp_type = {
 | |
| +--- a/drivers/net/ppp/pppoe.c
 | |
| ++++ b/drivers/net/ppp/pppoe.c
 | |
| +@@ -972,8 +972,30 @@ static int pppoe_xmit(struct ppp_channel
 | |
| + 	return __pppoe_xmit(sk, skb);
 | |
| + }
 | |
| + 
 | |
| ++static int pppoe_fill_forward_path(struct net_device_path_ctx *ctx,
 | |
| ++				   struct net_device_path *path,
 | |
| ++				   const struct ppp_channel *chan)
 | |
| ++{
 | |
| ++	struct sock *sk = (struct sock *)chan->private;
 | |
| ++	struct pppox_sock *po = pppox_sk(sk);
 | |
| ++	struct net_device *dev = po->pppoe_dev;
 | |
| ++
 | |
| ++	if (sock_flag(sk, SOCK_DEAD) ||
 | |
| ++	    !(sk->sk_state & PPPOX_CONNECTED) || !dev)
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	path->type = DEV_PATH_PPPOE;
 | |
| ++	path->encap.proto = htons(ETH_P_PPP_SES);
 | |
| ++	path->encap.id = be16_to_cpu(po->num);
 | |
| ++	path->dev = ctx->dev;
 | |
| ++	ctx->dev = dev;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static const struct ppp_channel_ops pppoe_chan_ops = {
 | |
| + 	.start_xmit = pppoe_xmit,
 | |
| ++	.fill_forward_path = pppoe_fill_forward_path,
 | |
| + };
 | |
| + 
 | |
| + static int pppoe_recvmsg(struct socket *sock, struct msghdr *m,
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -831,6 +831,7 @@ enum net_device_path_type {
 | |
| + 	DEV_PATH_ETHERNET = 0,
 | |
| + 	DEV_PATH_VLAN,
 | |
| + 	DEV_PATH_BRIDGE,
 | |
| ++	DEV_PATH_PPPOE,
 | |
| + };
 | |
| + 
 | |
| + struct net_device_path {
 | |
| +--- a/include/linux/ppp_channel.h
 | |
| ++++ b/include/linux/ppp_channel.h
 | |
| +@@ -28,6 +28,9 @@ struct ppp_channel_ops {
 | |
| + 	int	(*start_xmit)(struct ppp_channel *, struct sk_buff *);
 | |
| + 	/* Handle an ioctl call that has come in via /dev/ppp. */
 | |
| + 	int	(*ioctl)(struct ppp_channel *, unsigned int, unsigned long);
 | |
| ++	int	(*fill_forward_path)(struct net_device_path_ctx *,
 | |
| ++				     struct net_device_path *,
 | |
| ++				     const struct ppp_channel *);
 | |
| + };
 | |
| + 
 | |
| + struct ppp_channel {
 | |
| diff --git a/target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch b/target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0b85742290
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-12-net-dsa-resolve-forwarding-path-for-dsa-slave-ports.patch
 | |
| @@ -0,0 +1,60 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Thu, 4 Mar 2021 23:19:06 +0100
 | |
| +Subject: [PATCH] net: dsa: resolve forwarding path for dsa slave ports
 | |
| +
 | |
| +Add .ndo_fill_forward_path for dsa slave port devices
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -832,6 +832,7 @@ enum net_device_path_type {
 | |
| + 	DEV_PATH_VLAN,
 | |
| + 	DEV_PATH_BRIDGE,
 | |
| + 	DEV_PATH_PPPOE,
 | |
| ++	DEV_PATH_DSA,
 | |
| + };
 | |
| + 
 | |
| + struct net_device_path {
 | |
| +@@ -851,6 +852,10 @@ struct net_device_path {
 | |
| + 			u16		vlan_id;
 | |
| + 			__be16		vlan_proto;
 | |
| + 		} bridge;
 | |
| ++		struct {
 | |
| ++			int port;
 | |
| ++			u16 proto;
 | |
| ++		} dsa;
 | |
| + 	};
 | |
| + };
 | |
| + 
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -1617,6 +1617,21 @@ static struct devlink_port *dsa_slave_ge
 | |
| + 	return dp->ds->devlink ? &dp->devlink_port : NULL;
 | |
| + }
 | |
| + 
 | |
| ++static int dsa_slave_fill_forward_path(struct net_device_path_ctx *ctx,
 | |
| ++				       struct net_device_path *path)
 | |
| ++{
 | |
| ++	struct dsa_port *dp = dsa_slave_to_port(ctx->dev);
 | |
| ++	struct dsa_port *cpu_dp = dp->cpu_dp;
 | |
| ++
 | |
| ++	path->dev = ctx->dev;
 | |
| ++	path->type = DEV_PATH_DSA;
 | |
| ++	path->dsa.proto = cpu_dp->tag_ops->proto;
 | |
| ++	path->dsa.port = dp->index;
 | |
| ++	ctx->dev = cpu_dp->master;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static const struct net_device_ops dsa_slave_netdev_ops = {
 | |
| + 	.ndo_open	 	= dsa_slave_open,
 | |
| + 	.ndo_stop		= dsa_slave_close,
 | |
| +@@ -1642,6 +1657,7 @@ static const struct net_device_ops dsa_s
 | |
| + 	.ndo_vlan_rx_kill_vid	= dsa_slave_vlan_rx_kill_vid,
 | |
| + 	.ndo_get_devlink_port	= dsa_slave_get_devlink_port,
 | |
| + 	.ndo_change_mtu		= dsa_slave_change_mtu,
 | |
| ++	.ndo_fill_forward_path	= dsa_slave_fill_forward_path,
 | |
| + };
 | |
| + 
 | |
| + static struct device_type dsa_type = {
 | |
| diff --git a/target/linux/generic/pending-5.10/640-13-netfilter-flowtable-add-pppoe-support.patch b/target/linux/generic/pending-5.10/640-13-netfilter-flowtable-add-pppoe-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..524f466bf9
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-13-netfilter-flowtable-add-pppoe-support.patch
 | |
| @@ -0,0 +1,263 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Mon, 1 Mar 2021 23:52:49 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: add pppoe support
 | |
| +
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ppp/ppp_generic.c
 | |
| ++++ b/drivers/net/ppp/ppp_generic.c
 | |
| +@@ -1453,7 +1453,7 @@ static void ppp_dev_priv_destructor(stru
 | |
| + static int ppp_fill_forward_path(struct net_device_path_ctx *ctx,
 | |
| + 				 struct net_device_path *path)
 | |
| + {
 | |
| +-	struct ppp *ppp = netdev_priv(path->dev);
 | |
| ++	struct ppp *ppp = netdev_priv(ctx->dev);
 | |
| + 	struct ppp_channel *chan;
 | |
| + 	struct channel *pch;
 | |
| + 
 | |
| +--- a/drivers/net/ppp/pppoe.c
 | |
| ++++ b/drivers/net/ppp/pppoe.c
 | |
| +@@ -987,6 +987,7 @@ static int pppoe_fill_forward_path(struc
 | |
| + 	path->type = DEV_PATH_PPPOE;
 | |
| + 	path->encap.proto = htons(ETH_P_PPP_SES);
 | |
| + 	path->encap.id = be16_to_cpu(po->num);
 | |
| ++	memcpy(path->encap.h_dest, po->pppoe_pa.remote, ETH_ALEN);
 | |
| + 	path->dev = ctx->dev;
 | |
| + 	ctx->dev = dev;
 | |
| + 
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -842,6 +842,7 @@ struct net_device_path {
 | |
| + 		struct {
 | |
| + 			u16		id;
 | |
| + 			__be16		proto;
 | |
| ++			u8		h_dest[ETH_ALEN];
 | |
| + 		} encap;
 | |
| + 		struct {
 | |
| + 			enum {
 | |
| +--- a/net/netfilter/nf_flow_table_ip.c
 | |
| ++++ b/net/netfilter/nf_flow_table_ip.c
 | |
| +@@ -7,6 +7,9 @@
 | |
| + #include <linux/ip.h>
 | |
| + #include <linux/ipv6.h>
 | |
| + #include <linux/netdevice.h>
 | |
| ++#include <linux/if_ether.h>
 | |
| ++#include <linux/if_pppox.h>
 | |
| ++#include <linux/ppp_defs.h>
 | |
| + #include <net/ip.h>
 | |
| + #include <net/ipv6.h>
 | |
| + #include <net/ip6_route.h>
 | |
| +@@ -162,6 +165,8 @@ static bool ip_has_options(unsigned int
 | |
| + static void nf_flow_tuple_encap(struct sk_buff *skb,
 | |
| + 				struct flow_offload_tuple *tuple)
 | |
| + {
 | |
| ++	struct vlan_ethhdr *veth;
 | |
| ++	struct pppoe_hdr *phdr;
 | |
| + 	int i = 0;
 | |
| + 
 | |
| + 	if (skb_vlan_tag_present(skb)) {
 | |
| +@@ -169,23 +174,35 @@ static void nf_flow_tuple_encap(struct s
 | |
| + 		tuple->encap[i].proto = skb->vlan_proto;
 | |
| + 		i++;
 | |
| + 	}
 | |
| +-	if (skb->protocol == htons(ETH_P_8021Q)) {
 | |
| +-		struct vlan_ethhdr *veth = (struct vlan_ethhdr *)skb_mac_header(skb);
 | |
| +-
 | |
| ++	switch (skb->protocol) {
 | |
| ++	case htons(ETH_P_8021Q):
 | |
| ++		veth = (struct vlan_ethhdr *)skb_mac_header(skb);
 | |
| + 		tuple->encap[i].id = ntohs(veth->h_vlan_TCI);
 | |
| + 		tuple->encap[i].proto = skb->protocol;
 | |
| ++		break;
 | |
| ++	case htons(ETH_P_PPP_SES):
 | |
| ++		phdr = (struct pppoe_hdr *)skb_mac_header(skb);
 | |
| ++		tuple->encap[i].id = ntohs(phdr->sid);
 | |
| ++		tuple->encap[i].proto = skb->protocol;
 | |
| ++		break;
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| + static int nf_flow_tuple_ip(struct sk_buff *skb, const struct net_device *dev,
 | |
| +-			    struct flow_offload_tuple *tuple)
 | |
| ++			    struct flow_offload_tuple *tuple, u32 *nhoff)
 | |
| + {
 | |
| + 	unsigned int thoff, hdrsize, offset = 0;
 | |
| + 	struct flow_ports *ports;
 | |
| + 	struct iphdr *iph;
 | |
| + 
 | |
| +-	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| ++	switch (skb->protocol) {
 | |
| ++	case htons(ETH_P_8021Q):
 | |
| + 		offset += VLAN_HLEN;
 | |
| ++		break;
 | |
| ++	case htons(ETH_P_PPP_SES):
 | |
| ++		offset += PPPOE_SES_HLEN;
 | |
| ++		break;
 | |
| ++	}
 | |
| + 
 | |
| + 	if (!pskb_may_pull(skb, sizeof(*iph) + offset))
 | |
| + 		return -1;
 | |
| +@@ -226,6 +243,7 @@ static int nf_flow_tuple_ip(struct sk_bu
 | |
| + 	tuple->l4proto		= iph->protocol;
 | |
| + 	tuple->iifidx		= dev->ifindex;
 | |
| + 	nf_flow_tuple_encap(skb, tuple);
 | |
| ++	*nhoff = offset;
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -270,14 +288,36 @@ static unsigned int nf_flow_xmit_xfrm(st
 | |
| + 	return NF_STOLEN;
 | |
| + }
 | |
| + 
 | |
| ++static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
 | |
| ++{
 | |
| ++	__be16 proto;
 | |
| ++
 | |
| ++	proto = *((__be16 *)(skb_mac_header(skb) + ETH_HLEN +
 | |
| ++			     sizeof(struct pppoe_hdr)));
 | |
| ++	switch (proto) {
 | |
| ++	case htons(PPP_IP):
 | |
| ++		return htons(ETH_P_IP);
 | |
| ++	case htons(PPP_IPV6):
 | |
| ++		return htons(ETH_P_IPV6);
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static bool nf_flow_skb_encap_protocol(const struct sk_buff *skb, __be16 proto)
 | |
| + {
 | |
| +-	if (skb->protocol == htons(ETH_P_8021Q)) {
 | |
| +-		struct vlan_ethhdr *veth;
 | |
| ++	struct vlan_ethhdr *veth;
 | |
| + 
 | |
| ++	switch (skb->protocol) {
 | |
| ++	case htons(ETH_P_8021Q):
 | |
| + 		veth = (struct vlan_ethhdr *)skb_mac_header(skb);
 | |
| + 		if (veth->h_vlan_encapsulated_proto == proto)
 | |
| + 			return true;
 | |
| ++		break;
 | |
| ++	case htons(ETH_P_PPP_SES):
 | |
| ++		if (nf_flow_pppoe_proto(skb) == proto)
 | |
| ++			return true;
 | |
| ++		break;
 | |
| + 	}
 | |
| + 
 | |
| + 	return false;
 | |
| +@@ -294,12 +334,18 @@ static void nf_flow_encap_pop(struct sk_
 | |
| + 			__vlan_hwaccel_clear_tag(skb);
 | |
| + 			continue;
 | |
| + 		}
 | |
| +-		if (skb->protocol == htons(ETH_P_8021Q)) {
 | |
| ++		switch (skb->protocol) {
 | |
| ++		case htons(ETH_P_8021Q):
 | |
| + 			vlan_hdr = (struct vlan_hdr *)skb->data;
 | |
| + 			__skb_pull(skb, VLAN_HLEN);
 | |
| + 			vlan_set_encap_proto(skb, vlan_hdr);
 | |
| + 			skb_reset_network_header(skb);
 | |
| + 			break;
 | |
| ++		case htons(ETH_P_PPP_SES):
 | |
| ++			skb->protocol = nf_flow_pppoe_proto(skb);
 | |
| ++			skb_pull(skb, PPPOE_SES_HLEN);
 | |
| ++			skb_reset_network_header(skb);
 | |
| ++			break;
 | |
| + 		}
 | |
| + 	}
 | |
| + }
 | |
| +@@ -343,7 +389,7 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 	    !nf_flow_skb_encap_protocol(skb, htons(ETH_P_IP)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| +-	if (nf_flow_tuple_ip(skb, state->in, &tuple) < 0)
 | |
| ++	if (nf_flow_tuple_ip(skb, state->in, &tuple, &offset) < 0)
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| + 	tuplehash = flow_offload_lookup(flow_table, &tuple);
 | |
| +@@ -357,9 +403,6 @@ nf_flow_offload_ip_hook(void *priv, stru
 | |
| + 	if (unlikely(nf_flow_exceeds_mtu(skb, mtu)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| +-	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| +-		offset += VLAN_HLEN;
 | |
| +-
 | |
| + 	if (skb_try_make_writable(skb, sizeof(*iph) + offset))
 | |
| + 		return NF_DROP;
 | |
| + 
 | |
| +@@ -543,14 +586,20 @@ static int nf_flow_nat_ipv6(const struct
 | |
| + }
 | |
| + 
 | |
| + static int nf_flow_tuple_ipv6(struct sk_buff *skb, const struct net_device *dev,
 | |
| +-			      struct flow_offload_tuple *tuple)
 | |
| ++			      struct flow_offload_tuple *tuple, u32 *nhoff)
 | |
| + {
 | |
| + 	unsigned int thoff, hdrsize, offset = 0;
 | |
| + 	struct flow_ports *ports;
 | |
| + 	struct ipv6hdr *ip6h;
 | |
| + 
 | |
| +-	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| ++	switch (skb->protocol) {
 | |
| ++	case htons(ETH_P_8021Q):
 | |
| + 		offset += VLAN_HLEN;
 | |
| ++		break;
 | |
| ++	case htons(ETH_P_PPP_SES):
 | |
| ++		offset += PPPOE_SES_HLEN;
 | |
| ++		break;
 | |
| ++	}
 | |
| + 
 | |
| + 	if (!pskb_may_pull(skb, sizeof(*ip6h) + offset))
 | |
| + 		return -1;
 | |
| +@@ -586,6 +635,7 @@ static int nf_flow_tuple_ipv6(struct sk_
 | |
| + 	tuple->l4proto		= ip6h->nexthdr;
 | |
| + 	tuple->iifidx		= dev->ifindex;
 | |
| + 	nf_flow_tuple_encap(skb, tuple);
 | |
| ++	*nhoff = offset;
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -611,7 +661,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 	    !nf_flow_skb_encap_protocol(skb, htons(ETH_P_IPV6)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| +-	if (nf_flow_tuple_ipv6(skb, state->in, &tuple) < 0)
 | |
| ++	if (nf_flow_tuple_ipv6(skb, state->in, &tuple, &offset) < 0)
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| + 	tuplehash = flow_offload_lookup(flow_table, &tuple);
 | |
| +@@ -625,9 +675,6 @@ nf_flow_offload_ipv6_hook(void *priv, st
 | |
| + 	if (unlikely(nf_flow_exceeds_mtu(skb, mtu)))
 | |
| + 		return NF_ACCEPT;
 | |
| + 
 | |
| +-	if (skb->protocol == htons(ETH_P_8021Q))
 | |
| +-		offset += VLAN_HLEN;
 | |
| +-
 | |
| + 	ip6h = (struct ipv6hdr *)(skb_network_header(skb) + offset);
 | |
| + 	if (nf_flow_state_check(flow, ip6h->nexthdr, skb, sizeof(*ip6h)))
 | |
| + 		return NF_ACCEPT;
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -90,6 +90,7 @@ static void nft_dev_path_info(const stru
 | |
| + 		switch (path->type) {
 | |
| + 		case DEV_PATH_ETHERNET:
 | |
| + 		case DEV_PATH_VLAN:
 | |
| ++		case DEV_PATH_PPPOE:
 | |
| + 			info->indev = path->dev;
 | |
| + 			if (is_zero_ether_addr(info->h_source))
 | |
| + 				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
 | |
| +@@ -97,7 +98,7 @@ static void nft_dev_path_info(const stru
 | |
| + 			if (path->type == DEV_PATH_ETHERNET)
 | |
| + 				break;
 | |
| + 
 | |
| +-			/* DEV_PATH_VLAN */
 | |
| ++			/* DEV_PATH_VLAN and DEV_PATH_PPPOE */
 | |
| + 			if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
 | |
| + 				info->indev = NULL;
 | |
| + 				break;
 | |
| +@@ -106,6 +107,8 @@ static void nft_dev_path_info(const stru
 | |
| + 			info->encap[info->num_encaps].id = path->encap.id;
 | |
| + 			info->encap[info->num_encaps].proto = path->encap.proto;
 | |
| + 			info->num_encaps++;
 | |
| ++			if (path->type == DEV_PATH_PPPOE)
 | |
| ++				memcpy(info->h_dest, path->encap.h_dest, ETH_ALEN);
 | |
| + 			break;
 | |
| + 		case DEV_PATH_BRIDGE:
 | |
| + 			if (is_zero_ether_addr(info->h_source))
 | |
| diff --git a/target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-dsa-support.patch b/target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-dsa-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..7ff5dad1f7
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-14-netfilter-nft_flow_offload-add-dsa-support.patch
 | |
| @@ -0,0 +1,30 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Thu, 4 Mar 2021 19:22:55 +0100
 | |
| +Subject: [PATCH] netfilter: nft_flow_offload: add dsa support
 | |
| +
 | |
| +Replace the master ethernet device by the dsa slave port.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -89,6 +89,7 @@ static void nft_dev_path_info(const stru
 | |
| + 		path = &stack->path[i];
 | |
| + 		switch (path->type) {
 | |
| + 		case DEV_PATH_ETHERNET:
 | |
| ++		case DEV_PATH_DSA:
 | |
| + 		case DEV_PATH_VLAN:
 | |
| + 		case DEV_PATH_PPPOE:
 | |
| + 			info->indev = path->dev;
 | |
| +@@ -97,6 +98,10 @@ static void nft_dev_path_info(const stru
 | |
| + 
 | |
| + 			if (path->type == DEV_PATH_ETHERNET)
 | |
| + 				break;
 | |
| ++			if (path->type == DEV_PATH_DSA) {
 | |
| ++				i = stack->num_paths;
 | |
| ++				break;
 | |
| ++			}
 | |
| + 
 | |
| + 			/* DEV_PATH_VLAN and DEV_PATH_PPPOE */
 | |
| + 			if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
 | |
| diff --git a/target/linux/generic/pending-5.10/640-15-netfilter-flowtable-add-offload-support-for-xmit-pat.patch b/target/linux/generic/pending-5.10/640-15-netfilter-flowtable-add-offload-support-for-xmit-pat.patch
 | |
| new file mode 100644
 | |
| index 0000000000..696ea03332
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-15-netfilter-flowtable-add-offload-support-for-xmit-pat.patch
 | |
| @@ -0,0 +1,308 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Mon, 7 Dec 2020 20:31:44 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: add offload support for xmit path
 | |
| + types
 | |
| +
 | |
| +When the flow tuple xmit_type is set to FLOW_OFFLOAD_XMIT_DIRECT, the
 | |
| +dst_cache pointer is not valid, and the h_source/h_dest/ifidx out fields
 | |
| +need to be used.
 | |
| +
 | |
| +This patch also adds the FLOW_ACTION_VLAN_PUSH action to pass the VLAN
 | |
| +tag to the driver.
 | |
| +---
 | |
| +
 | |
| +--- a/net/netfilter/nf_flow_table_offload.c
 | |
| ++++ b/net/netfilter/nf_flow_table_offload.c
 | |
| +@@ -175,28 +175,45 @@ static int flow_offload_eth_src(struct n
 | |
| + 				enum flow_offload_tuple_dir dir,
 | |
| + 				struct nf_flow_rule *flow_rule)
 | |
| + {
 | |
| +-	const struct flow_offload_tuple *tuple = &flow->tuplehash[!dir].tuple;
 | |
| + 	struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule);
 | |
| + 	struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule);
 | |
| +-	struct net_device *dev;
 | |
| ++	const struct flow_offload_tuple *other_tuple, *this_tuple;
 | |
| ++	struct net_device *dev = NULL;
 | |
| ++	const unsigned char *addr;
 | |
| + 	u32 mask, val;
 | |
| + 	u16 val16;
 | |
| + 
 | |
| +-	dev = dev_get_by_index(net, tuple->iifidx);
 | |
| +-	if (!dev)
 | |
| +-		return -ENOENT;
 | |
| ++	this_tuple = &flow->tuplehash[dir].tuple;
 | |
| ++
 | |
| ++	switch (this_tuple->xmit_type) {
 | |
| ++	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| ++		addr = this_tuple->out.h_source;
 | |
| ++		break;
 | |
| ++	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| ++		other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| ++		dev = dev_get_by_index(net, other_tuple->iifidx);
 | |
| ++		if (!dev)
 | |
| ++			return -ENOENT;
 | |
| ++
 | |
| ++		addr = dev->dev_addr;
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| + 
 | |
| + 	mask = ~0xffff0000;
 | |
| +-	memcpy(&val16, dev->dev_addr, 2);
 | |
| ++	memcpy(&val16, addr, 2);
 | |
| + 	val = val16 << 16;
 | |
| + 	flow_offload_mangle(entry0, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 4,
 | |
| + 			    &val, &mask);
 | |
| + 
 | |
| + 	mask = ~0xffffffff;
 | |
| +-	memcpy(&val, dev->dev_addr + 2, 4);
 | |
| ++	memcpy(&val, addr + 2, 4);
 | |
| + 	flow_offload_mangle(entry1, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 8,
 | |
| + 			    &val, &mask);
 | |
| +-	dev_put(dev);
 | |
| ++
 | |
| ++	if (dev)
 | |
| ++		dev_put(dev);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -208,27 +225,40 @@ static int flow_offload_eth_dst(struct n
 | |
| + {
 | |
| + 	struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule);
 | |
| + 	struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule);
 | |
| +-	const void *daddr = &flow->tuplehash[!dir].tuple.src_v4;
 | |
| ++	const struct flow_offload_tuple *other_tuple, *this_tuple;
 | |
| + 	const struct dst_entry *dst_cache;
 | |
| + 	unsigned char ha[ETH_ALEN];
 | |
| + 	struct neighbour *n;
 | |
| ++	const void *daddr;
 | |
| + 	u32 mask, val;
 | |
| + 	u8 nud_state;
 | |
| + 	u16 val16;
 | |
| + 
 | |
| +-	dst_cache = flow->tuplehash[dir].tuple.dst_cache;
 | |
| +-	n = dst_neigh_lookup(dst_cache, daddr);
 | |
| +-	if (!n)
 | |
| +-		return -ENOENT;
 | |
| +-
 | |
| +-	read_lock_bh(&n->lock);
 | |
| +-	nud_state = n->nud_state;
 | |
| +-	ether_addr_copy(ha, n->ha);
 | |
| +-	read_unlock_bh(&n->lock);
 | |
| ++	this_tuple = &flow->tuplehash[dir].tuple;
 | |
| + 
 | |
| +-	if (!(nud_state & NUD_VALID)) {
 | |
| ++	switch (this_tuple->xmit_type) {
 | |
| ++	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| ++		ether_addr_copy(ha, this_tuple->out.h_dest);
 | |
| ++		break;
 | |
| ++	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| ++		other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| ++		daddr = &other_tuple->src_v4;
 | |
| ++		dst_cache = this_tuple->dst_cache;
 | |
| ++		n = dst_neigh_lookup(dst_cache, daddr);
 | |
| ++		if (!n)
 | |
| ++			return -ENOENT;
 | |
| ++
 | |
| ++		read_lock_bh(&n->lock);
 | |
| ++		nud_state = n->nud_state;
 | |
| ++		ether_addr_copy(ha, n->ha);
 | |
| ++		read_unlock_bh(&n->lock);
 | |
| + 		neigh_release(n);
 | |
| +-		return -ENOENT;
 | |
| ++
 | |
| ++		if (!(nud_state & NUD_VALID))
 | |
| ++			return -ENOENT;
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return -EOPNOTSUPP;
 | |
| + 	}
 | |
| + 
 | |
| + 	mask = ~0xffffffff;
 | |
| +@@ -241,7 +271,6 @@ static int flow_offload_eth_dst(struct n
 | |
| + 	val = val16;
 | |
| + 	flow_offload_mangle(entry1, FLOW_ACT_MANGLE_HDR_TYPE_ETH, 4,
 | |
| + 			    &val, &mask);
 | |
| +-	neigh_release(n);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -463,27 +492,52 @@ static void flow_offload_ipv4_checksum(s
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| +-static void flow_offload_redirect(const struct flow_offload *flow,
 | |
| ++static void flow_offload_redirect(struct net *net,
 | |
| ++				  const struct flow_offload *flow,
 | |
| + 				  enum flow_offload_tuple_dir dir,
 | |
| + 				  struct nf_flow_rule *flow_rule)
 | |
| + {
 | |
| +-	struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
 | |
| +-	struct rtable *rt;
 | |
| ++	const struct flow_offload_tuple *this_tuple, *other_tuple;
 | |
| ++	struct flow_action_entry *entry;
 | |
| ++	struct net_device *dev;
 | |
| ++	int ifindex;
 | |
| ++
 | |
| ++	this_tuple = &flow->tuplehash[dir].tuple;
 | |
| ++	switch (this_tuple->xmit_type) {
 | |
| ++	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| ++		this_tuple = &flow->tuplehash[dir].tuple;
 | |
| ++		ifindex = this_tuple->out.ifidx;
 | |
| ++		break;
 | |
| ++	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| ++		other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| ++		ifindex = other_tuple->iifidx;
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return;
 | |
| ++	}
 | |
| + 
 | |
| +-	rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
 | |
| ++	dev = dev_get_by_index(net, ifindex);
 | |
| ++	if (!dev)
 | |
| ++		return;
 | |
| ++
 | |
| ++	entry = flow_action_entry_next(flow_rule);
 | |
| + 	entry->id = FLOW_ACTION_REDIRECT;
 | |
| +-	entry->dev = rt->dst.dev;
 | |
| +-	dev_hold(rt->dst.dev);
 | |
| ++	entry->dev = dev;
 | |
| + }
 | |
| + 
 | |
| + static void flow_offload_encap_tunnel(const struct flow_offload *flow,
 | |
| + 				      enum flow_offload_tuple_dir dir,
 | |
| + 				      struct nf_flow_rule *flow_rule)
 | |
| + {
 | |
| ++	const struct flow_offload_tuple *this_tuple;
 | |
| + 	struct flow_action_entry *entry;
 | |
| + 	struct dst_entry *dst;
 | |
| + 
 | |
| +-	dst = flow->tuplehash[dir].tuple.dst_cache;
 | |
| ++	this_tuple = &flow->tuplehash[dir].tuple;
 | |
| ++	if (this_tuple->xmit_type == FLOW_OFFLOAD_XMIT_DIRECT)
 | |
| ++		return;
 | |
| ++
 | |
| ++	dst = this_tuple->dst_cache;
 | |
| + 	if (dst && dst->lwtstate) {
 | |
| + 		struct ip_tunnel_info *tun_info;
 | |
| + 
 | |
| +@@ -500,10 +554,15 @@ static void flow_offload_decap_tunnel(co
 | |
| + 				      enum flow_offload_tuple_dir dir,
 | |
| + 				      struct nf_flow_rule *flow_rule)
 | |
| + {
 | |
| ++	const struct flow_offload_tuple *other_tuple;
 | |
| + 	struct flow_action_entry *entry;
 | |
| + 	struct dst_entry *dst;
 | |
| + 
 | |
| +-	dst = flow->tuplehash[!dir].tuple.dst_cache;
 | |
| ++	other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| ++	if (other_tuple->xmit_type == FLOW_OFFLOAD_XMIT_DIRECT)
 | |
| ++		return;
 | |
| ++
 | |
| ++	dst = other_tuple->dst_cache;
 | |
| + 	if (dst && dst->lwtstate) {
 | |
| + 		struct ip_tunnel_info *tun_info;
 | |
| + 
 | |
| +@@ -515,10 +574,14 @@ static void flow_offload_decap_tunnel(co
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| +-int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow,
 | |
| +-			    enum flow_offload_tuple_dir dir,
 | |
| +-			    struct nf_flow_rule *flow_rule)
 | |
| ++static int
 | |
| ++nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow,
 | |
| ++			  enum flow_offload_tuple_dir dir,
 | |
| ++			  struct nf_flow_rule *flow_rule)
 | |
| + {
 | |
| ++	const struct flow_offload_tuple *other_tuple;
 | |
| ++	int i;
 | |
| ++
 | |
| + 	flow_offload_decap_tunnel(flow, dir, flow_rule);
 | |
| + 	flow_offload_encap_tunnel(flow, dir, flow_rule);
 | |
| + 
 | |
| +@@ -526,6 +589,26 @@ int nf_flow_rule_route_ipv4(struct net *
 | |
| + 	    flow_offload_eth_dst(net, flow, dir, flow_rule) < 0)
 | |
| + 		return -1;
 | |
| + 
 | |
| ++	other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| ++
 | |
| ++	for (i = 0; i < other_tuple->encap_num; i++) {
 | |
| ++		struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
 | |
| ++
 | |
| ++		entry->id = FLOW_ACTION_VLAN_PUSH;
 | |
| ++		entry->vlan.vid = other_tuple->encap[i].id;
 | |
| ++		entry->vlan.proto = other_tuple->encap[i].proto;
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow,
 | |
| ++			    enum flow_offload_tuple_dir dir,
 | |
| ++			    struct nf_flow_rule *flow_rule)
 | |
| ++{
 | |
| ++	if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0)
 | |
| ++		return -1;
 | |
| ++
 | |
| + 	if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
 | |
| + 		flow_offload_ipv4_snat(net, flow, dir, flow_rule);
 | |
| + 		flow_offload_port_snat(net, flow, dir, flow_rule);
 | |
| +@@ -538,7 +621,7 @@ int nf_flow_rule_route_ipv4(struct net *
 | |
| + 	    test_bit(NF_FLOW_DNAT, &flow->flags))
 | |
| + 		flow_offload_ipv4_checksum(net, flow, flow_rule);
 | |
| + 
 | |
| +-	flow_offload_redirect(flow, dir, flow_rule);
 | |
| ++	flow_offload_redirect(net, flow, dir, flow_rule);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -548,11 +631,7 @@ int nf_flow_rule_route_ipv6(struct net *
 | |
| + 			    enum flow_offload_tuple_dir dir,
 | |
| + 			    struct nf_flow_rule *flow_rule)
 | |
| + {
 | |
| +-	flow_offload_decap_tunnel(flow, dir, flow_rule);
 | |
| +-	flow_offload_encap_tunnel(flow, dir, flow_rule);
 | |
| +-
 | |
| +-	if (flow_offload_eth_src(net, flow, dir, flow_rule) < 0 ||
 | |
| +-	    flow_offload_eth_dst(net, flow, dir, flow_rule) < 0)
 | |
| ++	if (nf_flow_rule_route_common(net, flow, dir, flow_rule) < 0)
 | |
| + 		return -1;
 | |
| + 
 | |
| + 	if (test_bit(NF_FLOW_SNAT, &flow->flags)) {
 | |
| +@@ -564,7 +643,7 @@ int nf_flow_rule_route_ipv6(struct net *
 | |
| + 		flow_offload_port_dnat(net, flow, dir, flow_rule);
 | |
| + 	}
 | |
| + 
 | |
| +-	flow_offload_redirect(flow, dir, flow_rule);
 | |
| ++	flow_offload_redirect(net, flow, dir, flow_rule);
 | |
| + 
 | |
| + 	return 0;
 | |
| + }
 | |
| +@@ -578,10 +657,10 @@ nf_flow_offload_rule_alloc(struct net *n
 | |
| + 			   enum flow_offload_tuple_dir dir)
 | |
| + {
 | |
| + 	const struct nf_flowtable *flowtable = offload->flowtable;
 | |
| ++	const struct flow_offload_tuple *tuple, *other_tuple;
 | |
| + 	const struct flow_offload *flow = offload->flow;
 | |
| +-	const struct flow_offload_tuple *tuple;
 | |
| ++	struct dst_entry *other_dst = NULL;
 | |
| + 	struct nf_flow_rule *flow_rule;
 | |
| +-	struct dst_entry *other_dst;
 | |
| + 	int err = -ENOMEM;
 | |
| + 
 | |
| + 	flow_rule = kzalloc(sizeof(*flow_rule), GFP_KERNEL);
 | |
| +@@ -597,7 +676,10 @@ nf_flow_offload_rule_alloc(struct net *n
 | |
| + 	flow_rule->rule->match.key = &flow_rule->match.key;
 | |
| + 
 | |
| + 	tuple = &flow->tuplehash[dir].tuple;
 | |
| +-	other_dst = flow->tuplehash[!dir].tuple.dst_cache;
 | |
| ++	other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| ++	if (other_tuple->xmit_type == FLOW_OFFLOAD_XMIT_NEIGH)
 | |
| ++		other_dst = other_tuple->dst_cache;
 | |
| ++
 | |
| + 	err = nf_flow_rule_match(&flow_rule->match, tuple, other_dst);
 | |
| + 	if (err < 0)
 | |
| + 		goto err_flow_match;
 | |
| diff --git a/target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch b/target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4dade26f60
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-16-dsa-slave-add-support-for-TC_SETUP_FT.patch
 | |
| @@ -0,0 +1,53 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Mon, 18 Jan 2021 22:39:17 +0100
 | |
| +Subject: [PATCH] dsa: slave: add support for TC_SETUP_FT
 | |
| +
 | |
| +The dsa infrastructure provides a well-defined hierarchy of devices,
 | |
| +pass up the call to set up the flow block to the master device. From the
 | |
| +software dataplane, the netfilter infrastructure uses the dsa slave
 | |
| +devices to refer to the input and output device for the given skbuff.
 | |
| +Similarly, the flowtable definition in the ruleset refers to the dsa
 | |
| +slave port devices.
 | |
| +
 | |
| +This patch adds the glue code to call ndo_setup_tc with TC_SETUP_FT
 | |
| +with the master device via the dsa slave devices.
 | |
| +
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| +
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -1237,14 +1237,32 @@ static int dsa_slave_setup_tc_block(stru
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| ++static int dsa_slave_setup_ft_block(struct dsa_switch *ds, int port,
 | |
| ++				    void *type_data)
 | |
| ++{
 | |
| ++	struct dsa_port *cpu_dp = dsa_to_port(ds, port)->cpu_dp;
 | |
| ++	struct net_device *master = cpu_dp->master;
 | |
| ++
 | |
| ++	if (!master->netdev_ops->ndo_setup_tc)
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	return master->netdev_ops->ndo_setup_tc(master, TC_SETUP_FT, type_data);
 | |
| ++}
 | |
| ++
 | |
| + static int dsa_slave_setup_tc(struct net_device *dev, enum tc_setup_type type,
 | |
| + 			      void *type_data)
 | |
| + {
 | |
| + 	struct dsa_port *dp = dsa_slave_to_port(dev);
 | |
| + 	struct dsa_switch *ds = dp->ds;
 | |
| + 
 | |
| +-	if (type == TC_SETUP_BLOCK)
 | |
| ++	switch (type) {
 | |
| ++	case TC_SETUP_BLOCK:
 | |
| + 		return dsa_slave_setup_tc_block(dev, type_data);
 | |
| ++	case TC_SETUP_FT:
 | |
| ++		return dsa_slave_setup_ft_block(ds, dp->index, type_data);
 | |
| ++	default:
 | |
| ++		break;
 | |
| ++	}
 | |
| + 
 | |
| + 	if (!ds->ops->port_setup_tc)
 | |
| + 		return -EOPNOTSUPP;
 | |
| diff --git a/target/linux/generic/pending-5.10/640-17-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch b/target/linux/generic/pending-5.10/640-17-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch
 | |
| new file mode 100644
 | |
| index 0000000000..26d172bcf7
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-17-netfilter-nft_flow_offload-use-direct-xmit-if-hardwa.patch
 | |
| @@ -0,0 +1,108 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Thu, 4 Mar 2021 19:24:11 +0100
 | |
| +Subject: [PATCH] netfilter: nft_flow_offload: use direct xmit if
 | |
| + hardware offload is enabled
 | |
| +
 | |
| +If there is a forward path to reach an ethernet device and hardware
 | |
| +offload is enabled, then use the direct xmit path.
 | |
| +---
 | |
| +
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -131,6 +131,7 @@ struct flow_offload_tuple {
 | |
| + 		struct dst_entry	*dst_cache;
 | |
| + 		struct {
 | |
| + 			u32		ifidx;
 | |
| ++			u32		hw_ifidx;
 | |
| + 			u8		h_source[ETH_ALEN];
 | |
| + 			u8		h_dest[ETH_ALEN];
 | |
| + 		} out;
 | |
| +@@ -188,6 +189,7 @@ struct nf_flow_route {
 | |
| + 		} in;
 | |
| + 		struct {
 | |
| + 			u32			ifindex;
 | |
| ++			u32			hw_ifindex;
 | |
| + 			u8			h_source[ETH_ALEN];
 | |
| + 			u8			h_dest[ETH_ALEN];
 | |
| + 		} out;
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -106,6 +106,7 @@ static int flow_offload_fill_route(struc
 | |
| + 		memcpy(flow_tuple->out.h_source, route->tuple[dir].out.h_source,
 | |
| + 		       ETH_ALEN);
 | |
| + 		flow_tuple->out.ifidx = route->tuple[dir].out.ifindex;
 | |
| ++		flow_tuple->out.hw_ifidx = route->tuple[dir].out.hw_ifindex;
 | |
| + 		break;
 | |
| + 	case FLOW_OFFLOAD_XMIT_XFRM:
 | |
| + 	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| +--- a/net/netfilter/nf_flow_table_offload.c
 | |
| ++++ b/net/netfilter/nf_flow_table_offload.c
 | |
| +@@ -506,7 +506,7 @@ static void flow_offload_redirect(struct
 | |
| + 	switch (this_tuple->xmit_type) {
 | |
| + 	case FLOW_OFFLOAD_XMIT_DIRECT:
 | |
| + 		this_tuple = &flow->tuplehash[dir].tuple;
 | |
| +-		ifindex = this_tuple->out.ifidx;
 | |
| ++		ifindex = this_tuple->out.hw_ifidx;
 | |
| + 		break;
 | |
| + 	case FLOW_OFFLOAD_XMIT_NEIGH:
 | |
| + 		other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -66,6 +66,7 @@ static int nft_dev_fill_forward_path(con
 | |
| + struct nft_forward_info {
 | |
| + 	const struct net_device *indev;
 | |
| + 	const struct net_device *outdev;
 | |
| ++	const struct net_device *hw_outdev;
 | |
| + 	struct id {
 | |
| + 		__u16	id;
 | |
| + 		__be16	proto;
 | |
| +@@ -76,9 +77,18 @@ struct nft_forward_info {
 | |
| + 	enum flow_offload_xmit_type xmit_type;
 | |
| + };
 | |
| + 
 | |
| ++static bool nft_is_valid_ether_device(const struct net_device *dev)
 | |
| ++{
 | |
| ++	if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
 | |
| ++	    dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
 | |
| ++		return false;
 | |
| ++
 | |
| ++	return true;
 | |
| ++}
 | |
| ++
 | |
| + static void nft_dev_path_info(const struct net_device_path_stack *stack,
 | |
| + 			      struct nft_forward_info *info,
 | |
| +-			      unsigned char *ha)
 | |
| ++			      unsigned char *ha, struct nf_flowtable *flowtable)
 | |
| + {
 | |
| + 	const struct net_device_path *path;
 | |
| + 	int i;
 | |
| +@@ -140,6 +150,12 @@ static void nft_dev_path_info(const stru
 | |
| + 	}
 | |
| + 	if (!info->outdev)
 | |
| + 		info->outdev = info->indev;
 | |
| ++
 | |
| ++	info->hw_outdev = info->indev;
 | |
| ++
 | |
| ++	if (nf_flowtable_hw_offload(flowtable) &&
 | |
| ++	    nft_is_valid_ether_device(info->indev))
 | |
| ++		info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
 | |
| + }
 | |
| + 
 | |
| + static bool nft_flowtable_find_dev(const struct net_device *dev,
 | |
| +@@ -171,7 +187,7 @@ static void nft_dev_forward_path(struct
 | |
| + 	int i;
 | |
| + 
 | |
| + 	if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
 | |
| +-		nft_dev_path_info(&stack, &info, ha);
 | |
| ++		nft_dev_path_info(&stack, &info, ha, &ft->data);
 | |
| + 
 | |
| + 	if (!info.indev || !nft_flowtable_find_dev(info.indev, ft))
 | |
| + 		return;
 | |
| +@@ -187,6 +203,7 @@ static void nft_dev_forward_path(struct
 | |
| + 		memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
 | |
| + 		memcpy(route->tuple[dir].out.h_dest, info.h_dest, ETH_ALEN);
 | |
| + 		route->tuple[dir].out.ifindex = info.outdev->ifindex;
 | |
| ++		route->tuple[dir].out.hw_ifindex = info.hw_outdev->ifindex;
 | |
| + 		route->tuple[dir].xmit_type = info.xmit_type;
 | |
| + 	}
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/640-18-netfilter-nf_flow_table-fix-untagging-with-hardware-.patch b/target/linux/generic/pending-5.10/640-18-netfilter-nf_flow_table-fix-untagging-with-hardware-.patch
 | |
| new file mode 100644
 | |
| index 0000000000..18f43196eb
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-18-netfilter-nf_flow_table-fix-untagging-with-hardware-.patch
 | |
| @@ -0,0 +1,122 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Mon, 8 Mar 2021 12:06:44 +0100
 | |
| +Subject: [PATCH] netfilter: nf_flow_table: fix untagging with
 | |
| + hardware-offloaded bridge vlan_filtering
 | |
| +
 | |
| +When switchdev offloading is enabled, treat an untagged VLAN as tagged for
 | |
| +ingress only
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -849,6 +849,7 @@ struct net_device_path {
 | |
| + 				DEV_PATH_BR_VLAN_KEEP,
 | |
| + 				DEV_PATH_BR_VLAN_TAG,
 | |
| + 				DEV_PATH_BR_VLAN_UNTAG,
 | |
| ++				DEV_PATH_BR_VLAN_UNTAG_HW,
 | |
| + 			}		vlan_mode;
 | |
| + 			u16		vlan_id;
 | |
| + 			__be16		vlan_proto;
 | |
| +--- a/include/net/netfilter/nf_flow_table.h
 | |
| ++++ b/include/net/netfilter/nf_flow_table.h
 | |
| +@@ -123,9 +123,10 @@ struct flow_offload_tuple {
 | |
| + 	/* All members above are keys for lookups, see flow_offload_hash(). */
 | |
| + 	struct { }			__hash;
 | |
| + 
 | |
| +-	u8				dir:4,
 | |
| ++	u8				dir:2,
 | |
| + 					xmit_type:2,
 | |
| +-					encap_num:2;
 | |
| ++					encap_num:2,
 | |
| ++					in_vlan_ingress:2;
 | |
| + 	u16				mtu;
 | |
| + 	union {
 | |
| + 		struct dst_entry	*dst_cache;
 | |
| +@@ -185,7 +186,8 @@ struct nf_flow_route {
 | |
| + 				u16		id;
 | |
| + 				__be16		proto;
 | |
| + 			} encap[NF_FLOW_TABLE_ENCAP_MAX];
 | |
| +-			u8			num_encaps;
 | |
| ++			u8			num_encaps:2,
 | |
| ++						ingress_vlans:2;
 | |
| + 		} in;
 | |
| + 		struct {
 | |
| + 			u32			ifindex;
 | |
| +--- a/net/bridge/br_device.c
 | |
| ++++ b/net/bridge/br_device.c
 | |
| +@@ -435,6 +435,7 @@ static int br_fill_forward_path(struct n
 | |
| + 		ctx->vlan[ctx->num_vlans].proto = path->bridge.vlan_proto;
 | |
| + 		ctx->num_vlans++;
 | |
| + 		break;
 | |
| ++	case DEV_PATH_BR_VLAN_UNTAG_HW:
 | |
| + 	case DEV_PATH_BR_VLAN_UNTAG:
 | |
| + 		ctx->num_vlans--;
 | |
| + 		break;
 | |
| +--- a/net/bridge/br_vlan.c
 | |
| ++++ b/net/bridge/br_vlan.c
 | |
| +@@ -1374,6 +1374,8 @@ int br_vlan_fill_forward_path_mode(struc
 | |
| + 
 | |
| + 	if (path->bridge.vlan_mode == DEV_PATH_BR_VLAN_TAG)
 | |
| + 		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_KEEP;
 | |
| ++	else if (v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)
 | |
| ++		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG_HW;
 | |
| + 	else
 | |
| + 		path->bridge.vlan_mode = DEV_PATH_BR_VLAN_UNTAG;
 | |
| + 
 | |
| +--- a/net/netfilter/nf_flow_table_core.c
 | |
| ++++ b/net/netfilter/nf_flow_table_core.c
 | |
| +@@ -95,6 +95,8 @@ static int flow_offload_fill_route(struc
 | |
| + 	for (i = route->tuple[dir].in.num_encaps - 1; i >= 0; i--) {
 | |
| + 		flow_tuple->encap[j].id = route->tuple[dir].in.encap[i].id;
 | |
| + 		flow_tuple->encap[j].proto = route->tuple[dir].in.encap[i].proto;
 | |
| ++		if (route->tuple[dir].in.ingress_vlans & BIT(i))
 | |
| ++			flow_tuple->in_vlan_ingress |= BIT(j);
 | |
| + 		j++;
 | |
| + 	}
 | |
| + 	flow_tuple->encap_num = route->tuple[dir].in.num_encaps;
 | |
| +--- a/net/netfilter/nf_flow_table_offload.c
 | |
| ++++ b/net/netfilter/nf_flow_table_offload.c
 | |
| +@@ -592,8 +592,12 @@ nf_flow_rule_route_common(struct net *ne
 | |
| + 	other_tuple = &flow->tuplehash[!dir].tuple;
 | |
| + 
 | |
| + 	for (i = 0; i < other_tuple->encap_num; i++) {
 | |
| +-		struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
 | |
| ++		struct flow_action_entry *entry;
 | |
| + 
 | |
| ++		if (other_tuple->in_vlan_ingress & BIT(i))
 | |
| ++			continue;
 | |
| ++
 | |
| ++		entry = flow_action_entry_next(flow_rule);
 | |
| + 		entry->id = FLOW_ACTION_VLAN_PUSH;
 | |
| + 		entry->vlan.vid = other_tuple->encap[i].id;
 | |
| + 		entry->vlan.proto = other_tuple->encap[i].proto;
 | |
| +--- a/net/netfilter/nft_flow_offload.c
 | |
| ++++ b/net/netfilter/nft_flow_offload.c
 | |
| +@@ -72,6 +72,7 @@ struct nft_forward_info {
 | |
| + 		__be16	proto;
 | |
| + 	} encap[NF_FLOW_TABLE_ENCAP_MAX];
 | |
| + 	u8 num_encaps;
 | |
| ++	u8 ingress_vlans;
 | |
| + 	u8 h_source[ETH_ALEN];
 | |
| + 	u8 h_dest[ETH_ALEN];
 | |
| + 	enum flow_offload_xmit_type xmit_type;
 | |
| +@@ -130,6 +131,9 @@ static void nft_dev_path_info(const stru
 | |
| + 				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
 | |
| + 
 | |
| + 			switch (path->bridge.vlan_mode) {
 | |
| ++			case DEV_PATH_BR_VLAN_UNTAG_HW:
 | |
| ++				info->ingress_vlans |= BIT(info->num_encaps - 1);
 | |
| ++				break;
 | |
| + 			case DEV_PATH_BR_VLAN_TAG:
 | |
| + 				info->encap[info->num_encaps].id = path->bridge.vlan_id;
 | |
| + 				info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
 | |
| +@@ -198,6 +202,7 @@ static void nft_dev_forward_path(struct
 | |
| + 		route->tuple[!dir].in.encap[i].proto = info.encap[i].proto;
 | |
| + 	}
 | |
| + 	route->tuple[!dir].in.num_encaps = info.num_encaps;
 | |
| ++	route->tuple[!dir].in.ingress_vlans = info.ingress_vlans;
 | |
| + 
 | |
| + 	if (info.xmit_type == FLOW_OFFLOAD_XMIT_DIRECT) {
 | |
| + 		memcpy(route->tuple[dir].out.h_source, info.h_source, ETH_ALEN);
 | |
| diff --git a/target/linux/generic/pending-5.10/640-19-net-flow_offload-add-FLOW_ACTION_PPPOE_PUSH.patch b/target/linux/generic/pending-5.10/640-19-net-flow_offload-add-FLOW_ACTION_PPPOE_PUSH.patch
 | |
| new file mode 100644
 | |
| index 0000000000..3eaad27cdf
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-19-net-flow_offload-add-FLOW_ACTION_PPPOE_PUSH.patch
 | |
| @@ -0,0 +1,26 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Tue, 2 Mar 2021 00:51:31 +0100
 | |
| +Subject: [PATCH] net: flow_offload: add FLOW_ACTION_PPPOE_PUSH
 | |
| +
 | |
| +---
 | |
| +
 | |
| +--- a/include/net/flow_offload.h
 | |
| ++++ b/include/net/flow_offload.h
 | |
| +@@ -147,6 +147,7 @@ enum flow_action_id {
 | |
| + 	FLOW_ACTION_MPLS_POP,
 | |
| + 	FLOW_ACTION_MPLS_MANGLE,
 | |
| + 	FLOW_ACTION_GATE,
 | |
| ++	FLOW_ACTION_PPPOE_PUSH,
 | |
| + 	NUM_FLOW_ACTIONS,
 | |
| + };
 | |
| + 
 | |
| +@@ -271,6 +272,9 @@ struct flow_action_entry {
 | |
| + 			u32		num_entries;
 | |
| + 			struct action_gate_entry *entries;
 | |
| + 		} gate;
 | |
| ++		struct {				/* FLOW_ACTION_PPPOE_PUSH */
 | |
| ++			u16		sid;
 | |
| ++		} pppoe;
 | |
| + 	};
 | |
| + 	struct flow_action_cookie *cookie; /* user defined action cookie */
 | |
| + };
 | |
| diff --git a/target/linux/generic/pending-5.10/640-20-netfilter-flowtable-support-for-FLOW_ACTION_PPPOE_PU.patch b/target/linux/generic/pending-5.10/640-20-netfilter-flowtable-support-for-FLOW_ACTION_PPPOE_PU.patch
 | |
| new file mode 100644
 | |
| index 0000000000..fcafff1fff
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/640-20-netfilter-flowtable-support-for-FLOW_ACTION_PPPOE_PU.patch
 | |
| @@ -0,0 +1,31 @@
 | |
| +From: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +Date: Tue, 2 Mar 2021 01:01:50 +0100
 | |
| +Subject: [PATCH] netfilter: flowtable: support for
 | |
| + FLOW_ACTION_PPPOE_PUSH
 | |
| +
 | |
| +---
 | |
| +
 | |
| +--- a/net/netfilter/nf_flow_table_offload.c
 | |
| ++++ b/net/netfilter/nf_flow_table_offload.c
 | |
| +@@ -598,9 +598,18 @@ nf_flow_rule_route_common(struct net *ne
 | |
| + 			continue;
 | |
| + 
 | |
| + 		entry = flow_action_entry_next(flow_rule);
 | |
| +-		entry->id = FLOW_ACTION_VLAN_PUSH;
 | |
| +-		entry->vlan.vid = other_tuple->encap[i].id;
 | |
| +-		entry->vlan.proto = other_tuple->encap[i].proto;
 | |
| ++
 | |
| ++		switch (other_tuple->encap[i].proto) {
 | |
| ++		case htons(ETH_P_PPP_SES):
 | |
| ++			entry->id = FLOW_ACTION_PPPOE_PUSH;
 | |
| ++			entry->pppoe.sid = other_tuple->encap[i].id;
 | |
| ++			break;
 | |
| ++		case htons(ETH_P_8021Q):
 | |
| ++			entry->id = FLOW_ACTION_VLAN_PUSH;
 | |
| ++			entry->vlan.vid = other_tuple->encap[i].id;
 | |
| ++			entry->vlan.proto = other_tuple->encap[i].proto;
 | |
| ++			break;
 | |
| ++		}
 | |
| + 	}
 | |
| + 
 | |
| + 	return 0;
 | |
| diff --git a/target/linux/generic/pending-5.10/655-increase_skb_pad.patch b/target/linux/generic/pending-5.10/655-increase_skb_pad.patch
 | |
| new file mode 100644
 | |
| index 0000000000..ff39ddb8b3
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/655-increase_skb_pad.patch
 | |
| @@ -0,0 +1,20 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: kernel: add a few patches for avoiding unnecessary skb reallocations - significantly improves ethernet<->wireless performance
 | |
| +
 | |
| +lede-commit: 6f89cffc9add6939d44a6b54cf9a5e77849aa7fd
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/linux/skbuff.h | 2 +-
 | |
| + 1 file changed, 1 insertion(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/include/linux/skbuff.h
 | |
| ++++ b/include/linux/skbuff.h
 | |
| +@@ -2676,7 +2676,7 @@ static inline int pskb_network_may_pull(
 | |
| +  * NET_IP_ALIGN(2) + ethernet_header(14) + IP_header(20/40) + ports(8)
 | |
| +  */
 | |
| + #ifndef NET_SKB_PAD
 | |
| +-#define NET_SKB_PAD	max(32, L1_CACHE_BYTES)
 | |
| ++#define NET_SKB_PAD	max(64, L1_CACHE_BYTES)
 | |
| + #endif
 | |
| + 
 | |
| + int ___pskb_trim(struct sk_buff *skb, unsigned int len);
 | |
| diff --git a/target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch b/target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
 | |
| new file mode 100644
 | |
| index 0000000000..924baa0607
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/666-Add-support-for-MAP-E-FMRs-mesh-mode.patch
 | |
| @@ -0,0 +1,511 @@
 | |
| +From: Steven Barth <steven@midlink.org>
 | |
| +Subject: Add support for MAP-E FMRs (mesh mode)
 | |
| +
 | |
| +MAP-E FMRs (draft-ietf-softwire-map-10) are rules for IPv4-communication
 | |
| +between MAP CEs (mesh mode) without the need to forward such data to a
 | |
| +border relay. This is similar to how 6rd works but for IPv4 over IPv6.
 | |
| +
 | |
| +Signed-off-by: Steven Barth <cyrus@openwrt.org>
 | |
| +---
 | |
| + include/net/ip6_tunnel.h       |  13 ++
 | |
| + include/uapi/linux/if_tunnel.h |  13 ++
 | |
| + net/ipv6/ip6_tunnel.c          | 276 +++++++++++++++++++++++++++++++++++++++--
 | |
| + 3 files changed, 291 insertions(+), 11 deletions(-)
 | |
| +
 | |
| +--- a/include/net/ip6_tunnel.h
 | |
| ++++ b/include/net/ip6_tunnel.h
 | |
| +@@ -18,6 +18,18 @@
 | |
| + /* determine capability on a per-packet basis */
 | |
| + #define IP6_TNL_F_CAP_PER_PACKET 0x40000
 | |
| + 
 | |
| ++/* IPv6 tunnel FMR */
 | |
| ++struct __ip6_tnl_fmr {
 | |
| ++	struct __ip6_tnl_fmr *next; /* next fmr in list */
 | |
| ++	struct in6_addr ip6_prefix;
 | |
| ++	struct in_addr ip4_prefix;
 | |
| ++
 | |
| ++	__u8 ip6_prefix_len;
 | |
| ++	__u8 ip4_prefix_len;
 | |
| ++	__u8 ea_len;
 | |
| ++	__u8 offset;
 | |
| ++};
 | |
| ++
 | |
| + struct __ip6_tnl_parm {
 | |
| + 	char name[IFNAMSIZ];	/* name of tunnel device */
 | |
| + 	int link;		/* ifindex of underlying L2 interface */
 | |
| +@@ -29,6 +41,7 @@ struct __ip6_tnl_parm {
 | |
| + 	__u32 flags;		/* tunnel flags */
 | |
| + 	struct in6_addr laddr;	/* local tunnel end-point address */
 | |
| + 	struct in6_addr raddr;	/* remote tunnel end-point address */
 | |
| ++	struct __ip6_tnl_fmr *fmrs;	/* FMRs */
 | |
| + 
 | |
| + 	__be16			i_flags;
 | |
| + 	__be16			o_flags;
 | |
| +--- a/include/uapi/linux/if_tunnel.h
 | |
| ++++ b/include/uapi/linux/if_tunnel.h
 | |
| +@@ -77,10 +77,23 @@ enum {
 | |
| + 	IFLA_IPTUN_ENCAP_DPORT,
 | |
| + 	IFLA_IPTUN_COLLECT_METADATA,
 | |
| + 	IFLA_IPTUN_FWMARK,
 | |
| ++	IFLA_IPTUN_FMRS,
 | |
| + 	__IFLA_IPTUN_MAX,
 | |
| + };
 | |
| + #define IFLA_IPTUN_MAX	(__IFLA_IPTUN_MAX - 1)
 | |
| + 
 | |
| ++enum {
 | |
| ++	IFLA_IPTUN_FMR_UNSPEC,
 | |
| ++	IFLA_IPTUN_FMR_IP6_PREFIX,
 | |
| ++	IFLA_IPTUN_FMR_IP4_PREFIX,
 | |
| ++	IFLA_IPTUN_FMR_IP6_PREFIX_LEN,
 | |
| ++	IFLA_IPTUN_FMR_IP4_PREFIX_LEN,
 | |
| ++	IFLA_IPTUN_FMR_EA_LEN,
 | |
| ++	IFLA_IPTUN_FMR_OFFSET,
 | |
| ++	__IFLA_IPTUN_FMR_MAX,
 | |
| ++};
 | |
| ++#define IFLA_IPTUN_FMR_MAX (__IFLA_IPTUN_FMR_MAX - 1)
 | |
| ++
 | |
| + enum tunnel_encap_types {
 | |
| + 	TUNNEL_ENCAP_NONE,
 | |
| + 	TUNNEL_ENCAP_FOU,
 | |
| +--- a/net/ipv6/ip6_tunnel.c
 | |
| ++++ b/net/ipv6/ip6_tunnel.c
 | |
| +@@ -11,6 +11,9 @@
 | |
| +  *      linux/net/ipv6/sit.c and linux/net/ipv4/ipip.c
 | |
| +  *
 | |
| +  *      RFC 2473
 | |
| ++ *
 | |
| ++ *      Changes:
 | |
| ++ *      Steven Barth <cyrus@openwrt.org>:           MAP-E FMR support
 | |
| +  */
 | |
| + 
 | |
| + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 | |
| +@@ -67,9 +70,9 @@ static bool log_ecn_error = true;
 | |
| + module_param(log_ecn_error, bool, 0644);
 | |
| + MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
 | |
| + 
 | |
| +-static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2)
 | |
| ++static u32 HASH(const struct in6_addr *addr)
 | |
| + {
 | |
| +-	u32 hash = ipv6_addr_hash(addr1) ^ ipv6_addr_hash(addr2);
 | |
| ++	u32 hash = ipv6_addr_hash(addr);
 | |
| + 
 | |
| + 	return hash_32(hash, IP6_TUNNEL_HASH_SIZE_SHIFT);
 | |
| + }
 | |
| +@@ -144,17 +147,33 @@ static struct ip6_tnl *
 | |
| + ip6_tnl_lookup(struct net *net, int link,
 | |
| + 	       const struct in6_addr *remote, const struct in6_addr *local)
 | |
| + {
 | |
| +-	unsigned int hash = HASH(remote, local);
 | |
| ++	unsigned int hash = HASH(local);
 | |
| + 	struct ip6_tnl *t, *cand = NULL;
 | |
| + 	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 | |
| + 	struct in6_addr any;
 | |
| + 
 | |
| + 	for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
 | |
| + 		if (!ipv6_addr_equal(local, &t->parms.laddr) ||
 | |
| +-		    !ipv6_addr_equal(remote, &t->parms.raddr) ||
 | |
| + 		    !(t->dev->flags & IFF_UP))
 | |
| + 			continue;
 | |
| + 
 | |
| ++		if (!ipv6_addr_equal(remote, &t->parms.raddr)) {
 | |
| ++			struct __ip6_tnl_fmr *fmr;
 | |
| ++			bool found = false;
 | |
| ++
 | |
| ++			for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
 | |
| ++				if (!ipv6_prefix_equal(remote, &fmr->ip6_prefix,
 | |
| ++						       fmr->ip6_prefix_len))
 | |
| ++					continue;
 | |
| ++
 | |
| ++				found = true;
 | |
| ++				break;
 | |
| ++			}
 | |
| ++
 | |
| ++			if (!found)
 | |
| ++				continue;
 | |
| ++		}
 | |
| ++
 | |
| + 		if (link == t->parms.link)
 | |
| + 			return t;
 | |
| + 		else
 | |
| +@@ -162,7 +181,7 @@ ip6_tnl_lookup(struct net *net, int link
 | |
| + 	}
 | |
| + 
 | |
| + 	memset(&any, 0, sizeof(any));
 | |
| +-	hash = HASH(&any, local);
 | |
| ++	hash = HASH(local);
 | |
| + 	for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
 | |
| + 		if (!ipv6_addr_equal(local, &t->parms.laddr) ||
 | |
| + 		    !ipv6_addr_any(&t->parms.raddr) ||
 | |
| +@@ -175,7 +194,7 @@ ip6_tnl_lookup(struct net *net, int link
 | |
| + 			cand = t;
 | |
| + 	}
 | |
| + 
 | |
| +-	hash = HASH(remote, &any);
 | |
| ++	hash = HASH(&any);
 | |
| + 	for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
 | |
| + 		if (!ipv6_addr_equal(remote, &t->parms.raddr) ||
 | |
| + 		    !ipv6_addr_any(&t->parms.laddr) ||
 | |
| +@@ -223,7 +242,7 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n,
 | |
| + 
 | |
| + 	if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) {
 | |
| + 		prio = 1;
 | |
| +-		h = HASH(remote, local);
 | |
| ++		h = HASH(local);
 | |
| + 	}
 | |
| + 	return &ip6n->tnls[prio][h];
 | |
| + }
 | |
| +@@ -406,6 +425,12 @@ ip6_tnl_dev_uninit(struct net_device *de
 | |
| + 	struct net *net = t->net;
 | |
| + 	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 | |
| + 
 | |
| ++	while (t->parms.fmrs) {
 | |
| ++		struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
 | |
| ++		kfree(t->parms.fmrs);
 | |
| ++		t->parms.fmrs = next;
 | |
| ++	}
 | |
| ++
 | |
| + 	if (dev == ip6n->fb_tnl_dev)
 | |
| + 		RCU_INIT_POINTER(ip6n->tnls_wc[0], NULL);
 | |
| + 	else
 | |
| +@@ -822,6 +847,107 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(ip6_tnl_rcv_ctl);
 | |
| + 
 | |
| ++/**
 | |
| ++ * ip4ip6_fmr_calc - calculate target / source IPv6-address based on FMR
 | |
| ++ *   @dest: destination IPv6 address buffer
 | |
| ++ *   @skb: received socket buffer
 | |
| ++ *   @fmr: MAP FMR
 | |
| ++ *   @xmit: Calculate for xmit or rcv
 | |
| ++ **/
 | |
| ++static void ip4ip6_fmr_calc(struct in6_addr *dest,
 | |
| ++		const struct iphdr *iph, const uint8_t *end,
 | |
| ++		const struct __ip6_tnl_fmr *fmr, bool xmit)
 | |
| ++{
 | |
| ++	int psidlen = fmr->ea_len - (32 - fmr->ip4_prefix_len);
 | |
| ++	u8 *portp = NULL;
 | |
| ++	bool use_dest_addr;
 | |
| ++	const struct iphdr *dsth = iph;
 | |
| ++
 | |
| ++	if ((u8*)dsth >= end)
 | |
| ++		return;
 | |
| ++
 | |
| ++	/* find significant IP header */
 | |
| ++	if (iph->protocol == IPPROTO_ICMP) {
 | |
| ++		struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
 | |
| ++		if (ih && ((u8*)&ih[1]) <= end && (
 | |
| ++			ih->type == ICMP_DEST_UNREACH ||
 | |
| ++			ih->type == ICMP_SOURCE_QUENCH ||
 | |
| ++			ih->type == ICMP_TIME_EXCEEDED ||
 | |
| ++			ih->type == ICMP_PARAMETERPROB ||
 | |
| ++			ih->type == ICMP_REDIRECT))
 | |
| ++				dsth = (const struct iphdr*)&ih[1];
 | |
| ++	}
 | |
| ++
 | |
| ++	/* in xmit-path use dest port by default and source port only if
 | |
| ++		this is an ICMP reply to something else; vice versa in rcv-path */
 | |
| ++	use_dest_addr = (xmit && dsth == iph) || (!xmit && dsth != iph);
 | |
| ++
 | |
| ++	/* get dst port */
 | |
| ++	if (((u8*)&dsth[1]) <= end && (
 | |
| ++		dsth->protocol == IPPROTO_UDP ||
 | |
| ++		dsth->protocol == IPPROTO_TCP ||
 | |
| ++		dsth->protocol == IPPROTO_SCTP ||
 | |
| ++		dsth->protocol == IPPROTO_DCCP)) {
 | |
| ++			/* for UDP, TCP, SCTP and DCCP source and dest port
 | |
| ++			follow IPv4 header directly */
 | |
| ++			portp = ((u8*)dsth) + dsth->ihl * 4;
 | |
| ++
 | |
| ++			if (use_dest_addr)
 | |
| ++				portp += sizeof(u16);
 | |
| ++	} else if (iph->protocol == IPPROTO_ICMP) {
 | |
| ++		struct icmphdr *ih = (struct icmphdr*)(((u8*)dsth) + dsth->ihl * 4);
 | |
| ++
 | |
| ++		/* use icmp identifier as port */
 | |
| ++		if (((u8*)&ih) <= end && (
 | |
| ++		    (use_dest_addr && (
 | |
| ++		    ih->type == ICMP_ECHOREPLY ||
 | |
| ++			ih->type == ICMP_TIMESTAMPREPLY ||
 | |
| ++			ih->type == ICMP_INFO_REPLY ||
 | |
| ++			ih->type == ICMP_ADDRESSREPLY)) ||
 | |
| ++			(!use_dest_addr && (
 | |
| ++			ih->type == ICMP_ECHO ||
 | |
| ++			ih->type == ICMP_TIMESTAMP ||
 | |
| ++			ih->type == ICMP_INFO_REQUEST ||
 | |
| ++			ih->type == ICMP_ADDRESS)
 | |
| ++			)))
 | |
| ++				portp = (u8*)&ih->un.echo.id;
 | |
| ++	}
 | |
| ++
 | |
| ++	if ((portp && &portp[2] <= end) || psidlen == 0) {
 | |
| ++		int frombyte = fmr->ip6_prefix_len / 8;
 | |
| ++		int fromrem = fmr->ip6_prefix_len % 8;
 | |
| ++		int bytes = sizeof(struct in6_addr) - frombyte;
 | |
| ++		const u32 *addr = (use_dest_addr) ? &iph->daddr : &iph->saddr;
 | |
| ++		u64 eabits = ((u64)ntohl(*addr)) << (32 + fmr->ip4_prefix_len);
 | |
| ++		u64 t = 0;
 | |
| ++
 | |
| ++		/* extract PSID from port and add it to eabits */
 | |
| ++		u16 psidbits = 0;
 | |
| ++		if (psidlen > 0) {
 | |
| ++			psidbits = ((u16)portp[0]) << 8 | ((u16)portp[1]);
 | |
| ++			psidbits >>= 16 - psidlen - fmr->offset;
 | |
| ++			psidbits = (u16)(psidbits << (16 - psidlen));
 | |
| ++			eabits |= ((u64)psidbits) << (48 - (fmr->ea_len - psidlen));
 | |
| ++		}
 | |
| ++
 | |
| ++		/* rewrite destination address */
 | |
| ++		*dest = fmr->ip6_prefix;
 | |
| ++		memcpy(&dest->s6_addr[10], addr, sizeof(*addr));
 | |
| ++		dest->s6_addr16[7] = htons(psidbits >> (16 - psidlen));
 | |
| ++
 | |
| ++		if (bytes > sizeof(u64))
 | |
| ++			bytes = sizeof(u64);
 | |
| ++
 | |
| ++		/* insert eabits */
 | |
| ++		memcpy(&t, &dest->s6_addr[frombyte], bytes);
 | |
| ++		t = be64_to_cpu(t) & ~(((((u64)1) << fmr->ea_len) - 1)
 | |
| ++			<< (64 - fmr->ea_len - fromrem));
 | |
| ++		t = cpu_to_be64(t | (eabits >> fromrem));
 | |
| ++		memcpy(&dest->s6_addr[frombyte], &t, bytes);
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| + static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
 | |
| + 			 const struct tnl_ptk_info *tpi,
 | |
| + 			 struct metadata_dst *tun_dst,
 | |
| +@@ -874,6 +1000,27 @@ static int __ip6_tnl_rcv(struct ip6_tnl
 | |
| + 	skb_reset_network_header(skb);
 | |
| + 	memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
 | |
| + 
 | |
| ++	if (tpi->proto == htons(ETH_P_IP) && tunnel->parms.fmrs &&
 | |
| ++		!ipv6_addr_equal(&ipv6h->saddr, &tunnel->parms.raddr)) {
 | |
| ++			/* Packet didn't come from BR, so lookup FMR */
 | |
| ++			struct __ip6_tnl_fmr *fmr;
 | |
| ++			struct in6_addr expected = tunnel->parms.raddr;
 | |
| ++			for (fmr = tunnel->parms.fmrs; fmr; fmr = fmr->next)
 | |
| ++				if (ipv6_prefix_equal(&ipv6h->saddr,
 | |
| ++					&fmr->ip6_prefix, fmr->ip6_prefix_len))
 | |
| ++						break;
 | |
| ++
 | |
| ++			/* Check that IPv6 matches IPv4 source to prevent spoofing */
 | |
| ++			if (fmr)
 | |
| ++				ip4ip6_fmr_calc(&expected, ip_hdr(skb),
 | |
| ++						skb_tail_pointer(skb), fmr, false);
 | |
| ++
 | |
| ++			if (!ipv6_addr_equal(&ipv6h->saddr, &expected)) {
 | |
| ++				rcu_read_unlock();
 | |
| ++				goto drop;
 | |
| ++			}
 | |
| ++	}
 | |
| ++
 | |
| + 	__skb_tunnel_rx(skb, tunnel->dev, tunnel->net);
 | |
| + 
 | |
| + 	err = dscp_ecn_decapsulate(tunnel, ipv6h, skb);
 | |
| +@@ -1025,6 +1172,7 @@ static void init_tel_txopt(struct ipv6_t
 | |
| + 	opt->ops.opt_nflen = 8;
 | |
| + }
 | |
| + 
 | |
| ++
 | |
| + /**
 | |
| +  * ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
 | |
| +  *   @t: the outgoing tunnel device
 | |
| +@@ -1307,6 +1455,7 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
 | |
| + 		u8 protocol)
 | |
| + {
 | |
| + 	struct ip6_tnl *t = netdev_priv(dev);
 | |
| ++	struct __ip6_tnl_fmr *fmr;
 | |
| + 	struct ipv6hdr *ipv6h;
 | |
| + 	const struct iphdr  *iph;
 | |
| + 	int encap_limit = -1;
 | |
| +@@ -1406,6 +1555,18 @@ ipxip6_tnl_xmit(struct sk_buff *skb, str
 | |
| + 	fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
 | |
| + 	dsfield = INET_ECN_encapsulate(dsfield, orig_dsfield);
 | |
| + 
 | |
| ++	/* try to find matching FMR */
 | |
| ++	for (fmr = t->parms.fmrs; fmr; fmr = fmr->next) {
 | |
| ++		unsigned mshift = 32 - fmr->ip4_prefix_len;
 | |
| ++		if (ntohl(fmr->ip4_prefix.s_addr) >> mshift ==
 | |
| ++				ntohl(ip_hdr(skb)->daddr) >> mshift)
 | |
| ++			break;
 | |
| ++	}
 | |
| ++
 | |
| ++	/* change dstaddr according to FMR */
 | |
| ++	if (fmr)
 | |
| ++		ip4ip6_fmr_calc(&fl6.daddr, ip_hdr(skb), skb_tail_pointer(skb), fmr, true);
 | |
| ++
 | |
| + 	if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP6))
 | |
| + 		return -1;
 | |
| + 
 | |
| +@@ -1556,6 +1717,14 @@ ip6_tnl_change(struct ip6_tnl *t, const
 | |
| + 	t->parms.link = p->link;
 | |
| + 	t->parms.proto = p->proto;
 | |
| + 	t->parms.fwmark = p->fwmark;
 | |
| ++
 | |
| ++	while (t->parms.fmrs) {
 | |
| ++		struct __ip6_tnl_fmr *next = t->parms.fmrs->next;
 | |
| ++		kfree(t->parms.fmrs);
 | |
| ++		t->parms.fmrs = next;
 | |
| ++	}
 | |
| ++	t->parms.fmrs = p->fmrs;
 | |
| ++
 | |
| + 	dst_cache_reset(&t->dst_cache);
 | |
| + 	ip6_tnl_link_config(t);
 | |
| + 	return 0;
 | |
| +@@ -1594,6 +1763,7 @@ ip6_tnl_parm_from_user(struct __ip6_tnl_
 | |
| + 	p->flowinfo = u->flowinfo;
 | |
| + 	p->link = u->link;
 | |
| + 	p->proto = u->proto;
 | |
| ++	p->fmrs = NULL;
 | |
| + 	memcpy(p->name, u->name, sizeof(u->name));
 | |
| + }
 | |
| + 
 | |
| +@@ -1979,6 +2149,15 @@ static int ip6_tnl_validate(struct nlatt
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| ++static const struct nla_policy ip6_tnl_fmr_policy[IFLA_IPTUN_FMR_MAX + 1] = {
 | |
| ++	[IFLA_IPTUN_FMR_IP6_PREFIX] = { .len = sizeof(struct in6_addr) },
 | |
| ++	[IFLA_IPTUN_FMR_IP4_PREFIX] = { .len = sizeof(struct in_addr) },
 | |
| ++	[IFLA_IPTUN_FMR_IP6_PREFIX_LEN] = { .type = NLA_U8 },
 | |
| ++	[IFLA_IPTUN_FMR_IP4_PREFIX_LEN] = { .type = NLA_U8 },
 | |
| ++	[IFLA_IPTUN_FMR_EA_LEN] = { .type = NLA_U8 },
 | |
| ++	[IFLA_IPTUN_FMR_OFFSET] = { .type = NLA_U8 }
 | |
| ++};
 | |
| ++
 | |
| + static void ip6_tnl_netlink_parms(struct nlattr *data[],
 | |
| + 				  struct __ip6_tnl_parm *parms)
 | |
| + {
 | |
| +@@ -2016,6 +2195,46 @@ static void ip6_tnl_netlink_parms(struct
 | |
| + 
 | |
| + 	if (data[IFLA_IPTUN_FWMARK])
 | |
| + 		parms->fwmark = nla_get_u32(data[IFLA_IPTUN_FWMARK]);
 | |
| ++
 | |
| ++	if (data[IFLA_IPTUN_FMRS]) {
 | |
| ++		unsigned rem;
 | |
| ++		struct nlattr *fmr;
 | |
| ++		nla_for_each_nested(fmr, data[IFLA_IPTUN_FMRS], rem) {
 | |
| ++			struct nlattr *fmrd[IFLA_IPTUN_FMR_MAX + 1], *c;
 | |
| ++			struct __ip6_tnl_fmr *nfmr;
 | |
| ++
 | |
| ++			nla_parse_nested(fmrd, IFLA_IPTUN_FMR_MAX,
 | |
| ++				fmr, ip6_tnl_fmr_policy, NULL);
 | |
| ++
 | |
| ++			if (!(nfmr = kzalloc(sizeof(*nfmr), GFP_KERNEL)))
 | |
| ++				continue;
 | |
| ++
 | |
| ++			nfmr->offset = 6;
 | |
| ++
 | |
| ++			if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX]))
 | |
| ++				nla_memcpy(&nfmr->ip6_prefix, fmrd[IFLA_IPTUN_FMR_IP6_PREFIX],
 | |
| ++					sizeof(nfmr->ip6_prefix));
 | |
| ++
 | |
| ++			if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX]))
 | |
| ++				nla_memcpy(&nfmr->ip4_prefix, fmrd[IFLA_IPTUN_FMR_IP4_PREFIX],
 | |
| ++					sizeof(nfmr->ip4_prefix));
 | |
| ++
 | |
| ++			if ((c = fmrd[IFLA_IPTUN_FMR_IP6_PREFIX_LEN]))
 | |
| ++				nfmr->ip6_prefix_len = nla_get_u8(c);
 | |
| ++
 | |
| ++			if ((c = fmrd[IFLA_IPTUN_FMR_IP4_PREFIX_LEN]))
 | |
| ++				nfmr->ip4_prefix_len = nla_get_u8(c);
 | |
| ++
 | |
| ++			if ((c = fmrd[IFLA_IPTUN_FMR_EA_LEN]))
 | |
| ++				nfmr->ea_len = nla_get_u8(c);
 | |
| ++
 | |
| ++			if ((c = fmrd[IFLA_IPTUN_FMR_OFFSET]))
 | |
| ++				nfmr->offset = nla_get_u8(c);
 | |
| ++
 | |
| ++			nfmr->next = parms->fmrs;
 | |
| ++			parms->fmrs = nfmr;
 | |
| ++		}
 | |
| ++	}
 | |
| + }
 | |
| + 
 | |
| + static bool ip6_tnl_netlink_encap_parms(struct nlattr *data[],
 | |
| +@@ -2131,6 +2350,12 @@ static void ip6_tnl_dellink(struct net_d
 | |
| + 
 | |
| + static size_t ip6_tnl_get_size(const struct net_device *dev)
 | |
| + {
 | |
| ++	const struct ip6_tnl *t = netdev_priv(dev);
 | |
| ++	struct __ip6_tnl_fmr *c;
 | |
| ++	int fmrs = 0;
 | |
| ++	for (c = t->parms.fmrs; c; c = c->next)
 | |
| ++		++fmrs;
 | |
| ++
 | |
| + 	return
 | |
| + 		/* IFLA_IPTUN_LINK */
 | |
| + 		nla_total_size(4) +
 | |
| +@@ -2160,6 +2385,24 @@ static size_t ip6_tnl_get_size(const str
 | |
| + 		nla_total_size(0) +
 | |
| + 		/* IFLA_IPTUN_FWMARK */
 | |
| + 		nla_total_size(4) +
 | |
| ++		/* IFLA_IPTUN_FMRS */
 | |
| ++		nla_total_size(0) +
 | |
| ++		(
 | |
| ++			/* nest */
 | |
| ++			nla_total_size(0) +
 | |
| ++			/* IFLA_IPTUN_FMR_IP6_PREFIX */
 | |
| ++			nla_total_size(sizeof(struct in6_addr)) +
 | |
| ++			/* IFLA_IPTUN_FMR_IP4_PREFIX */
 | |
| ++			nla_total_size(sizeof(struct in_addr)) +
 | |
| ++			/* IFLA_IPTUN_FMR_EA_LEN */
 | |
| ++			nla_total_size(1) +
 | |
| ++			/* IFLA_IPTUN_FMR_IP6_PREFIX_LEN */
 | |
| ++			nla_total_size(1) +
 | |
| ++			/* IFLA_IPTUN_FMR_IP4_PREFIX_LEN */
 | |
| ++			nla_total_size(1) +
 | |
| ++			/* IFLA_IPTUN_FMR_OFFSET */
 | |
| ++			nla_total_size(1)
 | |
| ++		) * fmrs +
 | |
| + 		0;
 | |
| + }
 | |
| + 
 | |
| +@@ -2167,6 +2410,9 @@ static int ip6_tnl_fill_info(struct sk_b
 | |
| + {
 | |
| + 	struct ip6_tnl *tunnel = netdev_priv(dev);
 | |
| + 	struct __ip6_tnl_parm *parm = &tunnel->parms;
 | |
| ++	struct __ip6_tnl_fmr *c;
 | |
| ++	int fmrcnt = 0;
 | |
| ++	struct nlattr *fmrs;
 | |
| + 
 | |
| + 	if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
 | |
| + 	    nla_put_in6_addr(skb, IFLA_IPTUN_LOCAL, &parm->laddr) ||
 | |
| +@@ -2176,9 +2422,27 @@ static int ip6_tnl_fill_info(struct sk_b
 | |
| + 	    nla_put_be32(skb, IFLA_IPTUN_FLOWINFO, parm->flowinfo) ||
 | |
| + 	    nla_put_u32(skb, IFLA_IPTUN_FLAGS, parm->flags) ||
 | |
| + 	    nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->proto) ||
 | |
| +-	    nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark))
 | |
| ++	    nla_put_u32(skb, IFLA_IPTUN_FWMARK, parm->fwmark) ||
 | |
| ++	    !(fmrs = nla_nest_start(skb, IFLA_IPTUN_FMRS)))
 | |
| + 		goto nla_put_failure;
 | |
| + 
 | |
| ++	for (c = parm->fmrs; c; c = c->next) {
 | |
| ++		struct nlattr *fmr = nla_nest_start(skb, ++fmrcnt);
 | |
| ++		if (!fmr ||
 | |
| ++			nla_put(skb, IFLA_IPTUN_FMR_IP6_PREFIX,
 | |
| ++				sizeof(c->ip6_prefix), &c->ip6_prefix) ||
 | |
| ++			nla_put(skb, IFLA_IPTUN_FMR_IP4_PREFIX,
 | |
| ++				sizeof(c->ip4_prefix), &c->ip4_prefix) ||
 | |
| ++			nla_put_u8(skb, IFLA_IPTUN_FMR_IP6_PREFIX_LEN, c->ip6_prefix_len) ||
 | |
| ++			nla_put_u8(skb, IFLA_IPTUN_FMR_IP4_PREFIX_LEN, c->ip4_prefix_len) ||
 | |
| ++			nla_put_u8(skb, IFLA_IPTUN_FMR_EA_LEN, c->ea_len) ||
 | |
| ++			nla_put_u8(skb, IFLA_IPTUN_FMR_OFFSET, c->offset))
 | |
| ++				goto nla_put_failure;
 | |
| ++
 | |
| ++		nla_nest_end(skb, fmr);
 | |
| ++	}
 | |
| ++	nla_nest_end(skb, fmrs);
 | |
| ++
 | |
| + 	if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE, tunnel->encap.type) ||
 | |
| + 	    nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT, tunnel->encap.sport) ||
 | |
| + 	    nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT, tunnel->encap.dport) ||
 | |
| +@@ -2218,6 +2482,7 @@ static const struct nla_policy ip6_tnl_p
 | |
| + 	[IFLA_IPTUN_ENCAP_DPORT]	= { .type = NLA_U16 },
 | |
| + 	[IFLA_IPTUN_COLLECT_METADATA]	= { .type = NLA_FLAG },
 | |
| + 	[IFLA_IPTUN_FWMARK]		= { .type = NLA_U32 },
 | |
| ++	[IFLA_IPTUN_FMRS]		= { .type = NLA_NESTED },
 | |
| + };
 | |
| + 
 | |
| + static struct rtnl_link_ops ip6_link_ops __read_mostly = {
 | |
| diff --git a/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch b/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
 | |
| new file mode 100644
 | |
| index 0000000000..625cc430e2
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch
 | |
| @@ -0,0 +1,263 @@
 | |
| +From: Jonas Gorski <jogo@openwrt.org>
 | |
| +Subject: ipv6: allow rejecting with "source address failed policy"
 | |
| +
 | |
| +RFC6204 L-14 requires rejecting traffic from invalid addresses with
 | |
| +ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/
 | |
| +egress policy) on the LAN side, so add an appropriate rule for that.
 | |
| +
 | |
| +Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 | |
| +---
 | |
| + include/net/netns/ipv6.h       |  1 +
 | |
| + include/uapi/linux/fib_rules.h |  4 +++
 | |
| + include/uapi/linux/rtnetlink.h |  1 +
 | |
| + net/ipv4/fib_semantics.c       |  4 +++
 | |
| + net/ipv4/fib_trie.c            |  1 +
 | |
| + net/ipv4/ipmr.c                |  1 +
 | |
| + net/ipv6/fib6_rules.c          |  4 +++
 | |
| + net/ipv6/ip6mr.c               |  2 ++
 | |
| + net/ipv6/route.c               | 58 +++++++++++++++++++++++++++++++++++++++++-
 | |
| + 9 files changed, 75 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/include/net/netns/ipv6.h
 | |
| ++++ b/include/net/netns/ipv6.h
 | |
| +@@ -87,6 +87,7 @@ struct netns_ipv6 {
 | |
| + 	unsigned int		fib6_routes_require_src;
 | |
| + #endif
 | |
| + 	struct rt6_info         *ip6_prohibit_entry;
 | |
| ++	struct rt6_info		*ip6_policy_failed_entry;
 | |
| + 	struct rt6_info         *ip6_blk_hole_entry;
 | |
| + 	struct fib6_table       *fib6_local_tbl;
 | |
| + 	struct fib_rules_ops    *fib6_rules_ops;
 | |
| +--- a/include/uapi/linux/fib_rules.h
 | |
| ++++ b/include/uapi/linux/fib_rules.h
 | |
| +@@ -82,6 +82,10 @@ enum {
 | |
| + 	FR_ACT_BLACKHOLE,	/* Drop without notification */
 | |
| + 	FR_ACT_UNREACHABLE,	/* Drop with ENETUNREACH */
 | |
| + 	FR_ACT_PROHIBIT,	/* Drop with EACCES */
 | |
| ++	FR_ACT_RES9,
 | |
| ++	FR_ACT_RES10,
 | |
| ++	FR_ACT_RES11,
 | |
| ++	FR_ACT_POLICY_FAILED,	/* Drop with EACCES */
 | |
| + 	__FR_ACT_MAX,
 | |
| + };
 | |
| + 
 | |
| +--- a/include/uapi/linux/rtnetlink.h
 | |
| ++++ b/include/uapi/linux/rtnetlink.h
 | |
| +@@ -249,6 +249,7 @@ enum {
 | |
| + 	RTN_THROW,		/* Not in this table		*/
 | |
| + 	RTN_NAT,		/* Translate this address	*/
 | |
| + 	RTN_XRESOLVE,		/* Use external resolver	*/
 | |
| ++	RTN_POLICY_FAILED,	/* Failed ingress/egress policy */
 | |
| + 	__RTN_MAX
 | |
| + };
 | |
| + 
 | |
| +--- a/net/ipv4/fib_semantics.c
 | |
| ++++ b/net/ipv4/fib_semantics.c
 | |
| +@@ -141,6 +141,10 @@ const struct fib_prop fib_props[RTN_MAX
 | |
| + 		.error	= -EINVAL,
 | |
| + 		.scope	= RT_SCOPE_NOWHERE,
 | |
| + 	},
 | |
| ++	[RTN_POLICY_FAILED] = {
 | |
| ++		.error	= -EACCES,
 | |
| ++		.scope	= RT_SCOPE_UNIVERSE,
 | |
| ++	},
 | |
| + };
 | |
| + 
 | |
| + static void rt_fibinfo_free(struct rtable __rcu **rtp)
 | |
| +--- a/net/ipv4/fib_trie.c
 | |
| ++++ b/net/ipv4/fib_trie.c
 | |
| +@@ -2734,6 +2734,7 @@ static const char *const rtn_type_names[
 | |
| + 	[RTN_THROW] = "THROW",
 | |
| + 	[RTN_NAT] = "NAT",
 | |
| + 	[RTN_XRESOLVE] = "XRESOLVE",
 | |
| ++	[RTN_POLICY_FAILED] = "POLICY_FAILED",
 | |
| + };
 | |
| + 
 | |
| + static inline const char *rtn_type(char *buf, size_t len, unsigned int t)
 | |
| +--- a/net/ipv4/ipmr.c
 | |
| ++++ b/net/ipv4/ipmr.c
 | |
| +@@ -175,6 +175,7 @@ static int ipmr_rule_action(struct fib_r
 | |
| + 	case FR_ACT_UNREACHABLE:
 | |
| + 		return -ENETUNREACH;
 | |
| + 	case FR_ACT_PROHIBIT:
 | |
| ++	case FR_ACT_POLICY_FAILED:
 | |
| + 		return -EACCES;
 | |
| + 	case FR_ACT_BLACKHOLE:
 | |
| + 	default:
 | |
| +--- a/net/ipv6/fib6_rules.c
 | |
| ++++ b/net/ipv6/fib6_rules.c
 | |
| +@@ -220,6 +220,10 @@ static int __fib6_rule_action(struct fib
 | |
| + 		err = -EACCES;
 | |
| + 		rt = net->ipv6.ip6_prohibit_entry;
 | |
| + 		goto discard_pkt;
 | |
| ++	case FR_ACT_POLICY_FAILED:
 | |
| ++		err = -EACCES;
 | |
| ++		rt = net->ipv6.ip6_policy_failed_entry;
 | |
| ++		goto discard_pkt;
 | |
| + 	}
 | |
| + 
 | |
| + 	tb_id = fib_rule_get_table(rule, arg);
 | |
| +--- a/net/ipv6/ip6mr.c
 | |
| ++++ b/net/ipv6/ip6mr.c
 | |
| +@@ -163,6 +163,8 @@ static int ip6mr_rule_action(struct fib_
 | |
| + 		return -ENETUNREACH;
 | |
| + 	case FR_ACT_PROHIBIT:
 | |
| + 		return -EACCES;
 | |
| ++	case FR_ACT_POLICY_FAILED:
 | |
| ++		return -EACCES;
 | |
| + 	case FR_ACT_BLACKHOLE:
 | |
| + 	default:
 | |
| + 		return -EINVAL;
 | |
| +--- a/net/ipv6/route.c
 | |
| ++++ b/net/ipv6/route.c
 | |
| +@@ -94,6 +94,8 @@ static int		ip6_pkt_discard(struct sk_bu
 | |
| + static int		ip6_pkt_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
 | |
| + static int		ip6_pkt_prohibit(struct sk_buff *skb);
 | |
| + static int		ip6_pkt_prohibit_out(struct net *net, struct sock *sk, struct sk_buff *skb);
 | |
| ++static int		ip6_pkt_policy_failed(struct sk_buff *skb);
 | |
| ++static int		ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb);
 | |
| + static void		ip6_link_failure(struct sk_buff *skb);
 | |
| + static void		ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
 | |
| + 					   struct sk_buff *skb, u32 mtu,
 | |
| +@@ -309,6 +311,18 @@ static const struct rt6_info ip6_prohibi
 | |
| + 	.rt6i_flags	= (RTF_REJECT | RTF_NONEXTHOP),
 | |
| + };
 | |
| + 
 | |
| ++static const struct rt6_info ip6_policy_failed_entry_template = {
 | |
| ++	.dst = {
 | |
| ++		.__refcnt	= ATOMIC_INIT(1),
 | |
| ++		.__use		= 1,
 | |
| ++		.obsolete	= DST_OBSOLETE_FORCE_CHK,
 | |
| ++		.error		= -EACCES,
 | |
| ++		.input		= ip6_pkt_policy_failed,
 | |
| ++		.output		= ip6_pkt_policy_failed_out,
 | |
| ++	},
 | |
| ++	.rt6i_flags	= (RTF_REJECT | RTF_NONEXTHOP),
 | |
| ++};
 | |
| ++
 | |
| + static const struct rt6_info ip6_blk_hole_entry_template = {
 | |
| + 	.dst = {
 | |
| + 		.__refcnt	= ATOMIC_INIT(1),
 | |
| +@@ -1030,6 +1044,7 @@ static const int fib6_prop[RTN_MAX + 1]
 | |
| + 	[RTN_BLACKHOLE]	= -EINVAL,
 | |
| + 	[RTN_UNREACHABLE] = -EHOSTUNREACH,
 | |
| + 	[RTN_PROHIBIT]	= -EACCES,
 | |
| ++	[RTN_POLICY_FAILED] = -EACCES,
 | |
| + 	[RTN_THROW]	= -EAGAIN,
 | |
| + 	[RTN_NAT]	= -EINVAL,
 | |
| + 	[RTN_XRESOLVE]	= -EINVAL,
 | |
| +@@ -1065,6 +1080,10 @@ static void ip6_rt_init_dst_reject(struc
 | |
| + 		rt->dst.output = ip6_pkt_prohibit_out;
 | |
| + 		rt->dst.input = ip6_pkt_prohibit;
 | |
| + 		break;
 | |
| ++	case RTN_POLICY_FAILED:
 | |
| ++		rt->dst.output = ip6_pkt_policy_failed_out;
 | |
| ++		rt->dst.input = ip6_pkt_policy_failed;
 | |
| ++		break;
 | |
| + 	case RTN_THROW:
 | |
| + 	case RTN_UNREACHABLE:
 | |
| + 	default:
 | |
| +@@ -4414,6 +4433,17 @@ static int ip6_pkt_prohibit_out(struct n
 | |
| + 	return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
 | |
| + }
 | |
| + 
 | |
| ++static int ip6_pkt_policy_failed(struct sk_buff *skb)
 | |
| ++{
 | |
| ++	return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_INNOROUTES);
 | |
| ++}
 | |
| ++
 | |
| ++static int ip6_pkt_policy_failed_out(struct net *net, struct sock *sk, struct sk_buff *skb)
 | |
| ++{
 | |
| ++	skb->dev = skb_dst(skb)->dev;
 | |
| ++	return ip6_pkt_drop(skb, ICMPV6_POLICY_FAIL, IPSTATS_MIB_OUTNOROUTES);
 | |
| ++}
 | |
| ++
 | |
| + /*
 | |
| +  *	Allocate a dst for local (unicast / anycast) address.
 | |
| +  */
 | |
| +@@ -4894,7 +4924,8 @@ static int rtm_to_fib6_config(struct sk_
 | |
| + 	if (rtm->rtm_type == RTN_UNREACHABLE ||
 | |
| + 	    rtm->rtm_type == RTN_BLACKHOLE ||
 | |
| + 	    rtm->rtm_type == RTN_PROHIBIT ||
 | |
| +-	    rtm->rtm_type == RTN_THROW)
 | |
| ++	    rtm->rtm_type == RTN_THROW ||
 | |
| ++	    rtm->rtm_type == RTN_POLICY_FAILED)
 | |
| + 		cfg->fc_flags |= RTF_REJECT;
 | |
| + 
 | |
| + 	if (rtm->rtm_type == RTN_LOCAL)
 | |
| +@@ -6062,6 +6093,8 @@ static int ip6_route_dev_notify(struct n
 | |
| + #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 | |
| + 		net->ipv6.ip6_prohibit_entry->dst.dev = dev;
 | |
| + 		net->ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(dev);
 | |
| ++		net->ipv6.ip6_policy_failed_entry->dst.dev = dev;
 | |
| ++		net->ipv6.ip6_policy_failed_entry->rt6i_idev = in6_dev_get(dev);
 | |
| + 		net->ipv6.ip6_blk_hole_entry->dst.dev = dev;
 | |
| + 		net->ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(dev);
 | |
| + #endif
 | |
| +@@ -6073,6 +6106,7 @@ static int ip6_route_dev_notify(struct n
 | |
| + 		in6_dev_put_clear(&net->ipv6.ip6_null_entry->rt6i_idev);
 | |
| + #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 | |
| + 		in6_dev_put_clear(&net->ipv6.ip6_prohibit_entry->rt6i_idev);
 | |
| ++		in6_dev_put_clear(&net->ipv6.ip6_policy_failed_entry->rt6i_idev);
 | |
| + 		in6_dev_put_clear(&net->ipv6.ip6_blk_hole_entry->rt6i_idev);
 | |
| + #endif
 | |
| + 	}
 | |
| +@@ -6264,6 +6298,8 @@ static int __net_init ip6_route_net_init
 | |
| + 
 | |
| + #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 | |
| + 	net->ipv6.fib6_has_custom_rules = false;
 | |
| ++
 | |
| ++
 | |
| + 	net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
 | |
| + 					       sizeof(*net->ipv6.ip6_prohibit_entry),
 | |
| + 					       GFP_KERNEL);
 | |
| +@@ -6274,11 +6310,21 @@ static int __net_init ip6_route_net_init
 | |
| + 			 ip6_template_metrics, true);
 | |
| + 	INIT_LIST_HEAD(&net->ipv6.ip6_prohibit_entry->rt6i_uncached);
 | |
| + 
 | |
| ++	net->ipv6.ip6_policy_failed_entry =
 | |
| ++				kmemdup(&ip6_policy_failed_entry_template,
 | |
| ++				sizeof(*net->ipv6.ip6_policy_failed_entry), GFP_KERNEL);
 | |
| ++	if (!net->ipv6.ip6_policy_failed_entry)
 | |
| ++		goto out_ip6_prohibit_entry;
 | |
| ++	net->ipv6.ip6_policy_failed_entry->dst.ops = &net->ipv6.ip6_dst_ops;
 | |
| ++	dst_init_metrics(&net->ipv6.ip6_policy_failed_entry->dst,
 | |
| ++			 ip6_template_metrics, true);
 | |
| ++	INIT_LIST_HEAD(&net->ipv6.ip6_policy_failed_entry->rt6i_uncached);
 | |
| ++
 | |
| + 	net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
 | |
| + 					       sizeof(*net->ipv6.ip6_blk_hole_entry),
 | |
| + 					       GFP_KERNEL);
 | |
| + 	if (!net->ipv6.ip6_blk_hole_entry)
 | |
| +-		goto out_ip6_prohibit_entry;
 | |
| ++		goto out_ip6_policy_failed_entry;
 | |
| + 	net->ipv6.ip6_blk_hole_entry->dst.ops = &net->ipv6.ip6_dst_ops;
 | |
| + 	dst_init_metrics(&net->ipv6.ip6_blk_hole_entry->dst,
 | |
| + 			 ip6_template_metrics, true);
 | |
| +@@ -6305,6 +6351,8 @@ out:
 | |
| + 	return ret;
 | |
| + 
 | |
| + #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 | |
| ++out_ip6_policy_failed_entry:
 | |
| ++	kfree(net->ipv6.ip6_policy_failed_entry);
 | |
| + out_ip6_prohibit_entry:
 | |
| + 	kfree(net->ipv6.ip6_prohibit_entry);
 | |
| + out_ip6_null_entry:
 | |
| +@@ -6324,6 +6372,7 @@ static void __net_exit ip6_route_net_exi
 | |
| + 	kfree(net->ipv6.ip6_null_entry);
 | |
| + #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 | |
| + 	kfree(net->ipv6.ip6_prohibit_entry);
 | |
| ++	kfree(net->ipv6.ip6_policy_failed_entry);
 | |
| + 	kfree(net->ipv6.ip6_blk_hole_entry);
 | |
| + #endif
 | |
| + 	dst_entries_destroy(&net->ipv6.ip6_dst_ops);
 | |
| +@@ -6401,6 +6450,9 @@ void __init ip6_route_init_special_entri
 | |
| + 	init_net.ipv6.ip6_prohibit_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
 | |
| + 	init_net.ipv6.ip6_blk_hole_entry->dst.dev = init_net.loopback_dev;
 | |
| + 	init_net.ipv6.ip6_blk_hole_entry->rt6i_idev = in6_dev_get(init_net.loopback_dev);
 | |
| ++	init_net.ipv6.ip6_policy_failed_entry->dst.dev = init_net.loopback_dev;
 | |
| ++	init_net.ipv6.ip6_policy_failed_entry->rt6i_idev =
 | |
| ++		in6_dev_get(init_net.loopback_dev);
 | |
| +   #endif
 | |
| + }
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch b/target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0e7f35db89
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/671-net-provide-defines-for-_POLICY_FAILED-until-all-cod.patch
 | |
| @@ -0,0 +1,50 @@
 | |
| +From: Jonas Gorski <jogo@openwrt.org>
 | |
| +Subject: net: provide defines for _POLICY_FAILED until all code is updated
 | |
| +
 | |
| +Upstream introduced ICMPV6_POLICY_FAIL for code 5 of destination
 | |
| +unreachable, conflicting with our name.
 | |
| +
 | |
| +Add appropriate defines to allow our code to build with the new
 | |
| +name until we have updated our local patches for older kernels
 | |
| +and userspace packages.
 | |
| +
 | |
| +Signed-off-by: Jonas Gorski <jogo@openwrt.org>
 | |
| +---
 | |
| + include/uapi/linux/fib_rules.h | 2 ++
 | |
| + include/uapi/linux/icmpv6.h    | 2 ++
 | |
| + include/uapi/linux/rtnetlink.h | 2 ++
 | |
| + 3 files changed, 6 insertions(+)
 | |
| +
 | |
| +--- a/include/uapi/linux/fib_rules.h
 | |
| ++++ b/include/uapi/linux/fib_rules.h
 | |
| +@@ -89,6 +89,8 @@ enum {
 | |
| + 	__FR_ACT_MAX,
 | |
| + };
 | |
| + 
 | |
| ++#define FR_ACT_FAILED_POLICY FR_ACT_POLICY_FAILED
 | |
| ++
 | |
| + #define FR_ACT_MAX (__FR_ACT_MAX - 1)
 | |
| + 
 | |
| + #endif
 | |
| +--- a/include/uapi/linux/icmpv6.h
 | |
| ++++ b/include/uapi/linux/icmpv6.h
 | |
| +@@ -126,6 +126,8 @@ struct icmp6hdr {
 | |
| + #define ICMPV6_POLICY_FAIL		5
 | |
| + #define ICMPV6_REJECT_ROUTE		6
 | |
| + 
 | |
| ++#define ICMPV6_FAILED_POLICY		ICMPV6_POLICY_FAIL
 | |
| ++
 | |
| + /*
 | |
| +  *	Codes for Time Exceeded
 | |
| +  */
 | |
| +--- a/include/uapi/linux/rtnetlink.h
 | |
| ++++ b/include/uapi/linux/rtnetlink.h
 | |
| +@@ -253,6 +253,8 @@ enum {
 | |
| + 	__RTN_MAX
 | |
| + };
 | |
| + 
 | |
| ++#define RTN_FAILED_POLICY RTN_POLICY_FAILED
 | |
| ++
 | |
| + #define RTN_MAX (__RTN_MAX - 1)
 | |
| + 
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4e1ae4b2c8
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/680-NET-skip-GRO-for-foreign-MAC-addresses.patch
 | |
| @@ -0,0 +1,149 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: net: replace GRO optimization patch with a new one that supports VLANs/bridges with different MAC addresses
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + include/linux/netdevice.h |  2 ++
 | |
| + include/linux/skbuff.h    |  3 ++-
 | |
| + net/core/dev.c            | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 | |
| + net/ethernet/eth.c        | 18 +++++++++++++++++-
 | |
| + 4 files changed, 69 insertions(+), 2 deletions(-)
 | |
| +
 | |
| +--- a/include/linux/netdevice.h
 | |
| ++++ b/include/linux/netdevice.h
 | |
| +@@ -2029,6 +2029,8 @@ struct net_device {
 | |
| + 	struct netdev_hw_addr_list	mc;
 | |
| + 	struct netdev_hw_addr_list	dev_addrs;
 | |
| + 
 | |
| ++	unsigned char		local_addr_mask[MAX_ADDR_LEN];
 | |
| ++
 | |
| + #ifdef CONFIG_SYSFS
 | |
| + 	struct kset		*queues_kset;
 | |
| + #endif
 | |
| +--- a/include/linux/skbuff.h
 | |
| ++++ b/include/linux/skbuff.h
 | |
| +@@ -858,6 +858,7 @@ struct sk_buff {
 | |
| + #ifdef CONFIG_TLS_DEVICE
 | |
| + 	__u8			decrypted:1;
 | |
| + #endif
 | |
| ++	__u8			gro_skip:1;
 | |
| + 
 | |
| + #ifdef CONFIG_NET_SCHED
 | |
| + 	__u16			tc_index;	/* traffic control index */
 | |
| +--- a/net/core/dev.c
 | |
| ++++ b/net/core/dev.c
 | |
| +@@ -6017,6 +6017,9 @@ static enum gro_result dev_gro_receive(s
 | |
| + 	int same_flow;
 | |
| + 	int grow;
 | |
| + 
 | |
| ++	if (skb->gro_skip)
 | |
| ++		goto normal;
 | |
| ++
 | |
| + 	if (netif_elide_gro(skb->dev))
 | |
| + 		goto normal;
 | |
| + 
 | |
| +@@ -7985,6 +7988,48 @@ static void __netdev_adjacent_dev_unlink
 | |
| + 					   &upper_dev->adj_list.lower);
 | |
| + }
 | |
| + 
 | |
| ++static void __netdev_addr_mask(unsigned char *mask, const unsigned char *addr,
 | |
| ++			       struct net_device *dev)
 | |
| ++{
 | |
| ++	int i;
 | |
| ++
 | |
| ++	for (i = 0; i < dev->addr_len; i++)
 | |
| ++		mask[i] |= addr[i] ^ dev->dev_addr[i];
 | |
| ++}
 | |
| ++
 | |
| ++static void __netdev_upper_mask(unsigned char *mask, struct net_device *dev,
 | |
| ++				struct net_device *lower)
 | |
| ++{
 | |
| ++	struct net_device *cur;
 | |
| ++	struct list_head *iter;
 | |
| ++
 | |
| ++	netdev_for_each_upper_dev_rcu(dev, cur, iter) {
 | |
| ++		__netdev_addr_mask(mask, cur->dev_addr, lower);
 | |
| ++		__netdev_upper_mask(mask, cur, lower);
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++static void __netdev_update_addr_mask(struct net_device *dev)
 | |
| ++{
 | |
| ++	unsigned char mask[MAX_ADDR_LEN];
 | |
| ++	struct net_device *cur;
 | |
| ++	struct list_head *iter;
 | |
| ++
 | |
| ++	memset(mask, 0, sizeof(mask));
 | |
| ++	__netdev_upper_mask(mask, dev, dev);
 | |
| ++	memcpy(dev->local_addr_mask, mask, dev->addr_len);
 | |
| ++
 | |
| ++	netdev_for_each_lower_dev(dev, cur, iter)
 | |
| ++		__netdev_update_addr_mask(cur);
 | |
| ++}
 | |
| ++
 | |
| ++static void netdev_update_addr_mask(struct net_device *dev)
 | |
| ++{
 | |
| ++	rcu_read_lock();
 | |
| ++	__netdev_update_addr_mask(dev);
 | |
| ++	rcu_read_unlock();
 | |
| ++}
 | |
| ++
 | |
| + static int __netdev_upper_dev_link(struct net_device *dev,
 | |
| + 				   struct net_device *upper_dev, bool master,
 | |
| + 				   void *upper_priv, void *upper_info,
 | |
| +@@ -8036,6 +8081,7 @@ static int __netdev_upper_dev_link(struc
 | |
| + 	if (ret)
 | |
| + 		return ret;
 | |
| + 
 | |
| ++	netdev_update_addr_mask(dev);
 | |
| + 	ret = call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
 | |
| + 					    &changeupper_info.info);
 | |
| + 	ret = notifier_to_errno(ret);
 | |
| +@@ -8132,6 +8178,7 @@ static void __netdev_upper_dev_unlink(st
 | |
| + 
 | |
| + 	__netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
 | |
| + 
 | |
| ++	netdev_update_addr_mask(dev);
 | |
| + 	call_netdevice_notifiers_info(NETDEV_CHANGEUPPER,
 | |
| + 				      &changeupper_info.info);
 | |
| + 
 | |
| +@@ -8918,6 +8965,7 @@ int dev_set_mac_address(struct net_devic
 | |
| + 	if (err)
 | |
| + 		return err;
 | |
| + 	dev->addr_assign_type = NET_ADDR_SET;
 | |
| ++	netdev_update_addr_mask(dev);
 | |
| + 	call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
 | |
| + 	add_device_randomness(dev->dev_addr, dev->addr_len);
 | |
| + 	return 0;
 | |
| +--- a/net/ethernet/eth.c
 | |
| ++++ b/net/ethernet/eth.c
 | |
| +@@ -143,6 +143,18 @@ u32 eth_get_headlen(const struct net_dev
 | |
| + }
 | |
| + EXPORT_SYMBOL(eth_get_headlen);
 | |
| + 
 | |
| ++static inline bool
 | |
| ++eth_check_local_mask(const void *addr1, const void *addr2, const void *mask)
 | |
| ++{
 | |
| ++	const u16 *a1 = addr1;
 | |
| ++	const u16 *a2 = addr2;
 | |
| ++	const u16 *m = mask;
 | |
| ++
 | |
| ++	return (((a1[0] ^ a2[0]) & ~m[0]) |
 | |
| ++		((a1[1] ^ a2[1]) & ~m[1]) |
 | |
| ++		((a1[2] ^ a2[2]) & ~m[2]));
 | |
| ++}
 | |
| ++
 | |
| + /**
 | |
| +  * eth_type_trans - determine the packet's protocol ID.
 | |
| +  * @skb: received socket data
 | |
| +@@ -174,6 +186,10 @@ __be16 eth_type_trans(struct sk_buff *sk
 | |
| + 		} else {
 | |
| + 			skb->pkt_type = PACKET_OTHERHOST;
 | |
| + 		}
 | |
| ++
 | |
| ++		if (eth_check_local_mask(eth->h_dest, dev->dev_addr,
 | |
| ++					 dev->local_addr_mask))
 | |
| ++			skb->gro_skip = 1;
 | |
| + 	}
 | |
| + 
 | |
| + 	/*
 | |
| diff --git a/target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch b/target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch
 | |
| new file mode 100644
 | |
| index 0000000000..71fbfe9978
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/681-NET-add-of_get_mac_address_mtd.patch
 | |
| @@ -0,0 +1,135 @@
 | |
| +From: John Crispin <blogic@openwrt.org>
 | |
| +Subject: NET: add mtd-mac-address support to of_get_mac_address()
 | |
| +
 | |
| +Many embedded devices have information such as mac addresses stored inside mtd
 | |
| +devices. This patch allows us to add a property inside a node describing a
 | |
| +network interface. The new property points at a mtd partition with an offset
 | |
| +where the mac address can be found.
 | |
| +
 | |
| +Signed-off-by: John Crispin <blogic@openwrt.org>
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/of/of_net.c    |   37 +++++++++++++++++++++++++++++++++++++
 | |
| + include/linux/of_net.h |    1 +
 | |
| + 2 files changed, 38 insertions(+)
 | |
| +
 | |
| +--- a/drivers/of/of_net.c
 | |
| ++++ b/drivers/of/of_net.c
 | |
| +@@ -11,6 +11,7 @@
 | |
| + #include <linux/phy.h>
 | |
| + #include <linux/export.h>
 | |
| + #include <linux/device.h>
 | |
| ++#include <linux/mtd/mtd.h>
 | |
| + 
 | |
| + /**
 | |
| +  * of_get_phy_mode - Get phy mode for given device_node
 | |
| +@@ -45,7 +46,7 @@ int of_get_phy_mode(struct device_node *
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(of_get_phy_mode);
 | |
| + 
 | |
| +-static const void *of_get_mac_addr(struct device_node *np, const char *name)
 | |
| ++static void *of_get_mac_addr(struct device_node *np, const char *name)
 | |
| + {
 | |
| + 	struct property *pp = of_find_property(np, name, NULL);
 | |
| + 
 | |
| +@@ -78,6 +79,79 @@ static const void *of_get_mac_addr_nvmem
 | |
| + 	return mac;
 | |
| + }
 | |
| + 
 | |
| ++static const void *of_get_mac_address_mtd(struct device_node *np)
 | |
| ++{
 | |
| ++#ifdef CONFIG_MTD
 | |
| ++	struct device_node *mtd_np = NULL;
 | |
| ++	struct property *prop;
 | |
| ++	size_t retlen;
 | |
| ++	int size, ret;
 | |
| ++	struct mtd_info *mtd;
 | |
| ++	const char *part;
 | |
| ++	const __be32 *list;
 | |
| ++	phandle phandle;
 | |
| ++	u32 mac_inc = 0;
 | |
| ++	u8 mac[ETH_ALEN];
 | |
| ++	void *addr;
 | |
| ++	u32 inc_idx;
 | |
| ++
 | |
| ++	list = of_get_property(np, "mtd-mac-address", &size);
 | |
| ++	if (!list || (size != (2 * sizeof(*list))))
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	phandle = be32_to_cpup(list++);
 | |
| ++	if (phandle)
 | |
| ++		mtd_np = of_find_node_by_phandle(phandle);
 | |
| ++
 | |
| ++	if (!mtd_np)
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	part = of_get_property(mtd_np, "label", NULL);
 | |
| ++	if (!part)
 | |
| ++		part = mtd_np->name;
 | |
| ++
 | |
| ++	mtd = get_mtd_device_nm(part);
 | |
| ++	if (IS_ERR(mtd))
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, mac);
 | |
| ++	put_mtd_device(mtd);
 | |
| ++
 | |
| ++	if (of_property_read_u32(np, "mtd-mac-address-increment-byte", &inc_idx))
 | |
| ++		inc_idx = 5;
 | |
| ++	if (inc_idx > 5)
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	if (!of_property_read_u32(np, "mtd-mac-address-increment", &mac_inc))
 | |
| ++		mac[inc_idx] += mac_inc;
 | |
| ++
 | |
| ++	if (!is_valid_ether_addr(mac))
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	addr = of_get_mac_addr(np, "mac-address");
 | |
| ++	if (addr) {
 | |
| ++		memcpy(addr, mac, ETH_ALEN);
 | |
| ++		return addr;
 | |
| ++	}
 | |
| ++
 | |
| ++	prop = kzalloc(sizeof(*prop), GFP_KERNEL);
 | |
| ++	if (!prop)
 | |
| ++		return NULL;
 | |
| ++
 | |
| ++	prop->name = "mac-address";
 | |
| ++	prop->length = ETH_ALEN;
 | |
| ++	prop->value = kmemdup(mac, ETH_ALEN, GFP_KERNEL);
 | |
| ++	if (!prop->value || of_add_property(np, prop))
 | |
| ++		goto free;
 | |
| ++
 | |
| ++	return prop->value;
 | |
| ++free:
 | |
| ++	kfree(prop->value);
 | |
| ++	kfree(prop);
 | |
| ++#endif
 | |
| ++	return NULL;
 | |
| ++}
 | |
| ++
 | |
| + /**
 | |
| +  * Search the device tree for the best MAC address to use.  'mac-address' is
 | |
| +  * checked first, because that is supposed to contain to "most recent" MAC
 | |
| +@@ -98,12 +172,20 @@ static const void *of_get_mac_addr_nvmem
 | |
| +  * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
 | |
| +  * but is all zeros.
 | |
| +  *
 | |
| ++ *
 | |
| ++ * If a mtd-mac-address property exists, try to fetch the MAC address from the
 | |
| ++ * specified mtd device, and store it as a 'mac-address' property
 | |
| ++ *
 | |
| +  * Return: Will be a valid pointer on success and ERR_PTR in case of error.
 | |
| + */
 | |
| + const void *of_get_mac_address(struct device_node *np)
 | |
| + {
 | |
| + 	const void *addr;
 | |
| + 
 | |
| ++	addr = of_get_mac_address_mtd(np);
 | |
| ++	if (addr)
 | |
| ++		return addr;
 | |
| ++
 | |
| + 	addr = of_get_mac_addr(np, "mac-address");
 | |
| + 	if (addr)
 | |
| + 		return addr;
 | |
| diff --git a/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch b/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch
 | |
| new file mode 100644
 | |
| index 0000000000..9aa54082a5
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/703-phy-add-detach-callback-to-struct-phy_driver.patch
 | |
| @@ -0,0 +1,38 @@
 | |
| +From: Gabor Juhos <juhosg@openwrt.org>
 | |
| +Subject: generic: add detach callback to struct phy_driver
 | |
| +
 | |
| +lede-commit: fe61fc2d7d0b3fb348b502f68f98243b3ddf5867
 | |
| +
 | |
| +Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 | |
| +---
 | |
| + drivers/net/phy/phy_device.c | 3 +++
 | |
| + include/linux/phy.h          | 6 ++++++
 | |
| + 2 files changed, 9 insertions(+)
 | |
| +
 | |
| +--- a/drivers/net/phy/phy_device.c
 | |
| ++++ b/drivers/net/phy/phy_device.c
 | |
| +@@ -1651,6 +1651,9 @@ void phy_detach(struct phy_device *phyde
 | |
| + 	struct module *ndev_owner = NULL;
 | |
| + 	struct mii_bus *bus;
 | |
| + 
 | |
| ++	if (phydev->drv && phydev->drv->detach)
 | |
| ++		phydev->drv->detach(phydev);
 | |
| ++
 | |
| + 	if (phydev->sysfs_links) {
 | |
| + 		if (dev)
 | |
| + 			sysfs_remove_link(&dev->dev.kobj, "phydev");
 | |
| +--- a/include/linux/phy.h
 | |
| ++++ b/include/linux/phy.h
 | |
| +@@ -761,6 +761,12 @@ struct phy_driver {
 | |
| + 	/** @handle_interrupt: Override default interrupt handling */
 | |
| + 	irqreturn_t (*handle_interrupt)(struct phy_device *phydev);
 | |
| + 
 | |
| ++	/*
 | |
| ++	 * Called before an ethernet device is detached
 | |
| ++	 * from the PHY.
 | |
| ++	 */
 | |
| ++	void (*detach)(struct phy_device *phydev);
 | |
| ++
 | |
| + 	/** @remove: Clears up any memory if needed */
 | |
| + 	void (*remove)(struct phy_device *phydev);
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch b/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
 | |
| new file mode 100644
 | |
| index 0000000000..b063b10251
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/735-net-phy-at803x-fix-at8033-sgmii-mode.patch
 | |
| @@ -0,0 +1,51 @@
 | |
| +From: Roman Yeryomin <roman@advem.lv>
 | |
| +Subject: kernel: add at803x fix for sgmii mode
 | |
| +
 | |
| +Some (possibly broken) bootloaders incorreclty initialize at8033
 | |
| +phy. This patch enables sgmii autonegotiation mode.
 | |
| +
 | |
| +[john@phrozen.org: felix added this to his upstream queue]
 | |
| +
 | |
| +Signed-off-by: Roman Yeryomin <roman@advem.lv>
 | |
| +---
 | |
| + drivers/net/phy/at803x.c | 25 +++++++++++++++++++++++++
 | |
| + 1 file changed, 25 insertions(+)
 | |
| +
 | |
| +--- a/drivers/net/phy/at803x.c
 | |
| ++++ b/drivers/net/phy/at803x.c
 | |
| +@@ -76,6 +76,7 @@
 | |
| + #define AT803X_LOC_MAC_ADDR_32_47_OFFSET	0x804A
 | |
| + #define AT803X_REG_CHIP_CONFIG			0x1f
 | |
| + #define AT803X_BT_BX_REG_SEL			0x8000
 | |
| ++#define AT803X_SGMII_ANEG_EN			0x1000
 | |
| + 
 | |
| + #define AT803X_DEBUG_ADDR			0x1D
 | |
| + #define AT803X_DEBUG_DATA			0x1E
 | |
| +@@ -562,6 +563,27 @@ static int at8031_pll_config(struct phy_
 | |
| + static int at803x_config_init(struct phy_device *phydev)
 | |
| + {
 | |
| + 	int ret;
 | |
| ++	u32 v;
 | |
| ++
 | |
| ++	if (phydev->drv->phy_id == ATH8031_PHY_ID &&
 | |
| ++		phydev->interface == PHY_INTERFACE_MODE_SGMII)
 | |
| ++	{
 | |
| ++		v = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
 | |
| ++		/* select SGMII/fiber page */
 | |
| ++		ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG,
 | |
| ++						v & ~AT803X_BT_BX_REG_SEL);
 | |
| ++		if (ret)
 | |
| ++			return ret;
 | |
| ++		/* enable SGMII autonegotiation */
 | |
| ++		ret = phy_write(phydev, MII_BMCR, AT803X_SGMII_ANEG_EN);
 | |
| ++		if (ret)
 | |
| ++			return ret;
 | |
| ++		/* select copper page */
 | |
| ++		ret = phy_write(phydev, AT803X_REG_CHIP_CONFIG,
 | |
| ++						v | AT803X_BT_BX_REG_SEL);
 | |
| ++		if (ret)
 | |
| ++			return ret;
 | |
| ++	}
 | |
| + 
 | |
| + 	/* The RX and TX delay default is:
 | |
| + 	 *   after HW reset: RX delay enabled and TX delay disabled
 | |
| diff --git a/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch b/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch
 | |
| new file mode 100644
 | |
| index 0000000000..42b91fe4c3
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/760-net-dsa-mv88e6xxx-fix-vlan-setup.patch
 | |
| @@ -0,0 +1,27 @@
 | |
| +From a1b291f3f6c80a6c5ccad7283fc472d77a2a4763 Mon Sep 17 00:00:00 2001
 | |
| +From: Russell King <rmk+kernel@armlinux.org.uk>
 | |
| +Date: Sun, 22 Dec 2019 12:40:11 +0000
 | |
| +Subject: [PATCH] net: dsa: mv88e6xxx: fix vlan setup
 | |
| +
 | |
| +Provide an option that drivers can set to indicate they want to receive
 | |
| +vlan configuration even when vlan filtering is disabled. This is safe
 | |
| +for Marvell DSA bridges, which do not look up ingress traffic in the
 | |
| +VTU if the port is in 8021Q disabled state. Whether this change is
 | |
| +suitable for all DSA bridges is not known.
 | |
| +
 | |
| +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
 | |
| +Signed-off-by: DENG Qingfang <dqfext@gmail.com>
 | |
| +---
 | |
| + drivers/net/dsa/mv88e6xxx/chip.c |  1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| ++++ b/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| +@@ -2857,6 +2857,7 @@ static int mv88e6xxx_setup(struct dsa_sw
 | |
| + 
 | |
| + 	chip->ds = ds;
 | |
| + 	ds->slave_mii_bus = mv88e6xxx_default_mdio_bus(chip);
 | |
| ++	ds->configure_vlan_while_not_filtering = true;
 | |
| + 
 | |
| + 	mv88e6xxx_reg_lock(chip);
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch b/target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch
 | |
| new file mode 100644
 | |
| index 0000000000..3e654f4b04
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/761-net-dsa-mt7530-Support-EEE-features.patch
 | |
| @@ -0,0 +1,121 @@
 | |
| +From 9cfb2d426c38272f245e9e6f62b3552d1ed5852b Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?Ren=C3=A9=20van=20Dorst?= <opensource@vdorst.com>
 | |
| +Date: Tue, 21 Apr 2020 00:18:08 +0200
 | |
| +Subject: [PATCH] net: dsa: mt7530: Support EEE features
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +Signed-off-by: René van Dorst <opensource@vdorst.com>
 | |
| +--- a/drivers/net/dsa/mt7530.c
 | |
| ++++ b/drivers/net/dsa/mt7530.c
 | |
| +@@ -2264,9 +2264,13 @@ static void mt753x_phylink_mac_link_up(s
 | |
| + 	switch (speed) {
 | |
| + 	case SPEED_1000:
 | |
| + 		mcr |= PMCR_FORCE_SPEED_1000;
 | |
| ++		if (priv->eee_enable & BIT(port))
 | |
| ++			mcr |= PMCR_FORCE_EEE1G;
 | |
| + 		break;
 | |
| + 	case SPEED_100:
 | |
| + 		mcr |= PMCR_FORCE_SPEED_100;
 | |
| ++		if (priv->eee_enable & BIT(port))
 | |
| ++			mcr |= PMCR_FORCE_EEE100;
 | |
| + 		break;
 | |
| + 	}
 | |
| + 	if (duplex == DUPLEX_FULL) {
 | |
| +@@ -2507,6 +2511,54 @@ mt753x_phy_write(struct dsa_switch *ds,
 | |
| + 	return priv->info->phy_write(ds, port, regnum, val);
 | |
| + }
 | |
| + 
 | |
| ++static int mt7530_get_mac_eee(struct dsa_switch *ds, int port,
 | |
| ++			      struct ethtool_eee *e)
 | |
| ++{
 | |
| ++	struct mt7530_priv *priv = ds->priv;
 | |
| ++	u32 eeecr, pmsr;
 | |
| ++
 | |
| ++	e->eee_enabled = !!(priv->eee_enable & BIT(port));
 | |
| ++
 | |
| ++	if (e->eee_enabled) {
 | |
| ++		eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port));
 | |
| ++		e->tx_lpi_enabled = !(eeecr & LPI_MODE_EN);
 | |
| ++		e->tx_lpi_timer   = (eeecr >> 4) & 0xFFF;
 | |
| ++		pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
 | |
| ++		e->eee_active  = e->eee_enabled && !!(pmsr & PMSR_EEE1G);
 | |
| ++	} else {
 | |
| ++		e->tx_lpi_enabled = 0;
 | |
| ++		e->tx_lpi_timer = 0;
 | |
| ++		e->eee_active = 0;
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int mt7530_set_mac_eee(struct dsa_switch *ds, int port,
 | |
| ++			      struct ethtool_eee *e)
 | |
| ++{
 | |
| ++	struct mt7530_priv *priv = ds->priv;
 | |
| ++	u32 eeecr;
 | |
| ++
 | |
| ++	if (e->tx_lpi_enabled && e->tx_lpi_timer > 0xFFF)
 | |
| ++		return -EINVAL;
 | |
| ++
 | |
| ++	if (e->eee_enabled) {
 | |
| ++		priv->eee_enable |= BIT(port);
 | |
| ++		//MT7530_PMEEECR_P
 | |
| ++		eeecr = mt7530_read(priv, MT7530_PMEEECR_P(port));
 | |
| ++		eeecr &= 0xFFFF0000;
 | |
| ++		if (!e->tx_lpi_enabled)
 | |
| ++			eeecr |= LPI_MODE_EN;
 | |
| ++		eeecr = LPI_THRESH(e->tx_lpi_timer);
 | |
| ++		mt7530_write(priv, MT7530_PMEEECR_P(port), eeecr);
 | |
| ++	} else {
 | |
| ++		priv->eee_enable &= ~(BIT(port));
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| + static const struct dsa_switch_ops mt7530_switch_ops = {
 | |
| + 	.get_tag_protocol	= mtk_get_tag_protocol,
 | |
| + 	.setup			= mt753x_setup,
 | |
| +@@ -2535,6 +2587,8 @@ static const struct dsa_switch_ops mt753
 | |
| + 	.phylink_mac_an_restart	= mt753x_phylink_mac_an_restart,
 | |
| + 	.phylink_mac_link_down	= mt753x_phylink_mac_link_down,
 | |
| + 	.phylink_mac_link_up	= mt753x_phylink_mac_link_up,
 | |
| ++	.get_mac_eee		= mt7530_get_mac_eee,
 | |
| ++	.set_mac_eee		= mt7530_set_mac_eee,
 | |
| + };
 | |
| + 
 | |
| + static const struct mt753x_info mt753x_table[] = {
 | |
| +--- a/drivers/net/dsa/mt7530.h
 | |
| ++++ b/drivers/net/dsa/mt7530.h
 | |
| +@@ -240,6 +240,8 @@ enum mt7530_vlan_port_attr {
 | |
| + #define  PMCR_RX_EN			BIT(13)
 | |
| + #define  PMCR_BACKOFF_EN		BIT(9)
 | |
| + #define  PMCR_BACKPR_EN			BIT(8)
 | |
| ++#define  PMCR_FORCE_EEE1G		BIT(7)
 | |
| ++#define  PMCR_FORCE_EEE100		BIT(6)
 | |
| + #define  PMCR_TX_FC_EN			BIT(5)
 | |
| + #define  PMCR_RX_FC_EN			BIT(4)
 | |
| + #define  PMCR_FORCE_SPEED_1000		BIT(3)
 | |
| +@@ -289,6 +291,12 @@ enum mt7530_vlan_port_attr {
 | |
| + #define MT7531_DBG_CNT(x)		(0x3018 + (x) * 0x100)
 | |
| + #define  MT7531_DIS_CLR			BIT(31)
 | |
| + 
 | |
| ++#define MT7530_PMEEECR_P(x)		(0x3004 + (x) * 0x100)
 | |
| ++#define  WAKEUP_TIME_1000(x)		((x & 0xFF) << 24)
 | |
| ++#define  WAKEUP_TIME_100(x)		((x & 0xFF) << 16)
 | |
| ++#define  LPI_THRESH(x)			((x & 0xFFF) << 4)
 | |
| ++#define  LPI_MODE_EN			BIT(0)
 | |
| ++
 | |
| + /* Register for MIB */
 | |
| + #define MT7530_PORT_MIB_COUNTER(x)	(0x4000 + (x) * 0x100)
 | |
| + #define MT7530_MIB_CCR			0x4fe0
 | |
| +@@ -732,6 +740,7 @@ struct mt7530_priv {
 | |
| + 	unsigned int		p5_intf_sel;
 | |
| + 	u8			mirror_rx;
 | |
| + 	u8			mirror_tx;
 | |
| ++	u8			eee_enable;
 | |
| + 
 | |
| + 	struct mt7530_port	ports[MT7530_NUM_PORTS];
 | |
| + 	/* protect among processes for registers access*/
 | |
| diff --git a/target/linux/generic/pending-5.10/762-net-bridge-switchdev-Refactor-br_switchdev_fdb_notif.patch b/target/linux/generic/pending-5.10/762-net-bridge-switchdev-Refactor-br_switchdev_fdb_notif.patch
 | |
| new file mode 100644
 | |
| index 0000000000..fbc8342b0e
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/762-net-bridge-switchdev-Refactor-br_switchdev_fdb_notif.patch
 | |
| @@ -0,0 +1,77 @@
 | |
| +From 46fe6cecb296d850c1ee2b333e57093ac4b733f3 Mon Sep 17 00:00:00 2001
 | |
| +From: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Date: Sat, 16 Jan 2021 02:25:09 +0100
 | |
| +Subject: [PATCH] net: bridge: switchdev: Refactor br_switchdev_fdb_notify
 | |
| +
 | |
| +Instead of having to add more and more arguments to
 | |
| +br_switchdev_fdb_call_notifiers, get rid of it and build the info
 | |
| +struct directly in br_switchdev_fdb_notify.
 | |
| +
 | |
| +Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
 | |
| +---
 | |
| + net/bridge/br_switchdev.c | 41 +++++++++++----------------------------
 | |
| + 1 file changed, 11 insertions(+), 30 deletions(-)
 | |
| +
 | |
| +--- a/net/bridge/br_switchdev.c
 | |
| ++++ b/net/bridge/br_switchdev.c
 | |
| +@@ -102,25 +102,16 @@ int br_switchdev_set_port_flag(struct ne
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| +-static void
 | |
| +-br_switchdev_fdb_call_notifiers(bool adding, const unsigned char *mac,
 | |
| +-				u16 vid, struct net_device *dev,
 | |
| +-				bool added_by_user, bool offloaded)
 | |
| +-{
 | |
| +-	struct switchdev_notifier_fdb_info info;
 | |
| +-	unsigned long notifier_type;
 | |
| +-
 | |
| +-	info.addr = mac;
 | |
| +-	info.vid = vid;
 | |
| +-	info.added_by_user = added_by_user;
 | |
| +-	info.offloaded = offloaded;
 | |
| +-	notifier_type = adding ? SWITCHDEV_FDB_ADD_TO_DEVICE : SWITCHDEV_FDB_DEL_TO_DEVICE;
 | |
| +-	call_switchdev_notifiers(notifier_type, dev, &info.info, NULL);
 | |
| +-}
 | |
| +-
 | |
| + void
 | |
| + br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
 | |
| + {
 | |
| ++	struct switchdev_notifier_fdb_info info = {
 | |
| ++		.addr = fdb->key.addr.addr,
 | |
| ++		.vid = fdb->key.vlan_id,
 | |
| ++		.added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags),
 | |
| ++		.offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags),
 | |
| ++	};
 | |
| ++
 | |
| + 	if (!fdb->dst)
 | |
| + 		return;
 | |
| + 	if (test_bit(BR_FDB_LOCAL, &fdb->flags))
 | |
| +@@ -128,22 +119,12 @@ br_switchdev_fdb_notify(const struct net
 | |
| + 
 | |
| + 	switch (type) {
 | |
| + 	case RTM_DELNEIGH:
 | |
| +-		br_switchdev_fdb_call_notifiers(false, fdb->key.addr.addr,
 | |
| +-						fdb->key.vlan_id,
 | |
| +-						fdb->dst->dev,
 | |
| +-						test_bit(BR_FDB_ADDED_BY_USER,
 | |
| +-							 &fdb->flags),
 | |
| +-						test_bit(BR_FDB_OFFLOADED,
 | |
| +-							 &fdb->flags));
 | |
| ++		call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_DEVICE,
 | |
| ++					 fdb->dst->dev, &info.info, NULL);
 | |
| + 		break;
 | |
| + 	case RTM_NEWNEIGH:
 | |
| +-		br_switchdev_fdb_call_notifiers(true, fdb->key.addr.addr,
 | |
| +-						fdb->key.vlan_id,
 | |
| +-						fdb->dst->dev,
 | |
| +-						test_bit(BR_FDB_ADDED_BY_USER,
 | |
| +-							 &fdb->flags),
 | |
| +-						test_bit(BR_FDB_OFFLOADED,
 | |
| +-							 &fdb->flags));
 | |
| ++		call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_DEVICE,
 | |
| ++					 fdb->dst->dev, &info.info, NULL);
 | |
| + 		break;
 | |
| + 	}
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/763-net-bridge-switchdev-Include-local-flag-in-FDB-notif.patch b/target/linux/generic/pending-5.10/763-net-bridge-switchdev-Include-local-flag-in-FDB-notif.patch
 | |
| new file mode 100644
 | |
| index 0000000000..41374c88df
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/763-net-bridge-switchdev-Include-local-flag-in-FDB-notif.patch
 | |
| @@ -0,0 +1,42 @@
 | |
| +From ec5be4f79026282925ae383caa431a8d41e3456a Mon Sep 17 00:00:00 2001
 | |
| +From: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Date: Sat, 16 Jan 2021 02:25:10 +0100
 | |
| +Subject: [PATCH] net: bridge: switchdev: Include local flag in FDB
 | |
| + notifications
 | |
| +
 | |
| +Some switchdev drivers, notably DSA, ignore all dynamically learned
 | |
| +address notifications (!added_by_user) as these are autonomously added
 | |
| +by the switch. Previously, such a notification was indistinguishable
 | |
| +from a local address notification. Include a local bit in the
 | |
| +notification so that the two classes can be discriminated.
 | |
| +
 | |
| +This allows DSA-like devices to add local addresses to the hardware
 | |
| +FDB (with the CPU as the destination), thereby avoiding flows towards
 | |
| +the CPU being flooded by the switch as unknown unicast.
 | |
| +
 | |
| +Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +---
 | |
| + include/net/switchdev.h   | 1 +
 | |
| + net/bridge/br_switchdev.c | 1 +
 | |
| + 2 files changed, 2 insertions(+)
 | |
| +
 | |
| +--- a/include/net/switchdev.h
 | |
| ++++ b/include/net/switchdev.h
 | |
| +@@ -224,6 +224,7 @@ struct switchdev_notifier_fdb_info {
 | |
| + 	const unsigned char *addr;
 | |
| + 	u16 vid;
 | |
| + 	u8 added_by_user:1,
 | |
| ++	   local:1,
 | |
| + 	   offloaded:1;
 | |
| + };
 | |
| + 
 | |
| +--- a/net/bridge/br_switchdev.c
 | |
| ++++ b/net/bridge/br_switchdev.c
 | |
| +@@ -109,6 +109,7 @@ br_switchdev_fdb_notify(const struct net
 | |
| + 		.addr = fdb->key.addr.addr,
 | |
| + 		.vid = fdb->key.vlan_id,
 | |
| + 		.added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags),
 | |
| ++		.local = test_bit(BR_FDB_LOCAL, &fdb->flags),
 | |
| + 		.offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags),
 | |
| + 	};
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/764-net-bridge-switchdev-Send-FDB-notifications-for-host.patch b/target/linux/generic/pending-5.10/764-net-bridge-switchdev-Send-FDB-notifications-for-host.patch
 | |
| new file mode 100644
 | |
| index 0000000000..0e773888df
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/764-net-bridge-switchdev-Send-FDB-notifications-for-host.patch
 | |
| @@ -0,0 +1,96 @@
 | |
| +From 2e50fd9322047253c327550b4485cf8761035a8c Mon Sep 17 00:00:00 2001
 | |
| +From: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Date: Sat, 16 Jan 2021 02:25:11 +0100
 | |
| +Subject: [PATCH] net: bridge: switchdev: Send FDB notifications for host
 | |
| + addresses
 | |
| +
 | |
| +Treat addresses added to the bridge itself in the same way as regular
 | |
| +ports and send out a notification so that drivers may sync it down to
 | |
| +the hardware FDB.
 | |
| +
 | |
| +Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +---
 | |
| + net/bridge/br_fdb.c       |  4 ++--
 | |
| + net/bridge/br_private.h   |  7 ++++---
 | |
| + net/bridge/br_switchdev.c | 11 +++++------
 | |
| + 3 files changed, 11 insertions(+), 11 deletions(-)
 | |
| +
 | |
| +--- a/net/bridge/br_fdb.c
 | |
| ++++ b/net/bridge/br_fdb.c
 | |
| +@@ -602,7 +602,7 @@ void br_fdb_update(struct net_bridge *br
 | |
| + 			/* fastpath: update of existing entry */
 | |
| + 			if (unlikely(source != fdb->dst &&
 | |
| + 				     !test_bit(BR_FDB_STICKY, &fdb->flags))) {
 | |
| +-				br_switchdev_fdb_notify(fdb, RTM_DELNEIGH);
 | |
| ++				br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH);
 | |
| + 				fdb->dst = source;
 | |
| + 				fdb_modified = true;
 | |
| + 				/* Take over HW learned entry */
 | |
| +@@ -735,7 +735,7 @@ static void fdb_notify(struct net_bridge
 | |
| + 	int err = -ENOBUFS;
 | |
| + 
 | |
| + 	if (swdev_notify)
 | |
| +-		br_switchdev_fdb_notify(fdb, type);
 | |
| ++		br_switchdev_fdb_notify(br, fdb, type);
 | |
| + 
 | |
| + 	skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
 | |
| + 	if (skb == NULL)
 | |
| +--- a/net/bridge/br_private.h
 | |
| ++++ b/net/bridge/br_private.h
 | |
| +@@ -1527,8 +1527,8 @@ bool nbp_switchdev_allowed_egress(const
 | |
| + int br_switchdev_set_port_flag(struct net_bridge_port *p,
 | |
| + 			       unsigned long flags,
 | |
| + 			       unsigned long mask);
 | |
| +-void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb,
 | |
| +-			     int type);
 | |
| ++void br_switchdev_fdb_notify(struct net_bridge *br,
 | |
| ++			     const struct net_bridge_fdb_entry *fdb, int type);
 | |
| + int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
 | |
| + 			       struct netlink_ext_ack *extack);
 | |
| + int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
 | |
| +@@ -1574,7 +1574,8 @@ static inline int br_switchdev_port_vlan
 | |
| + }
 | |
| + 
 | |
| + static inline void
 | |
| +-br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
 | |
| ++br_switchdev_fdb_notify(struct net_bridge *br,
 | |
| ++			const struct net_bridge_fdb_entry *fdb, int type)
 | |
| + {
 | |
| + }
 | |
| + 
 | |
| +--- a/net/bridge/br_switchdev.c
 | |
| ++++ b/net/bridge/br_switchdev.c
 | |
| +@@ -103,7 +103,8 @@ int br_switchdev_set_port_flag(struct ne
 | |
| + }
 | |
| + 
 | |
| + void
 | |
| +-br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type)
 | |
| ++br_switchdev_fdb_notify(struct net_bridge *br,
 | |
| ++			const struct net_bridge_fdb_entry *fdb, int type)
 | |
| + {
 | |
| + 	struct switchdev_notifier_fdb_info info = {
 | |
| + 		.addr = fdb->key.addr.addr,
 | |
| +@@ -112,20 +113,19 @@ br_switchdev_fdb_notify(const struct net
 | |
| + 		.local = test_bit(BR_FDB_LOCAL, &fdb->flags),
 | |
| + 		.offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags),
 | |
| + 	};
 | |
| ++	struct net_device *dev = fdb->dst ? fdb->dst->dev : br->dev;
 | |
| + 
 | |
| +-	if (!fdb->dst)
 | |
| +-		return;
 | |
| + 	if (test_bit(BR_FDB_LOCAL, &fdb->flags))
 | |
| + 		return;
 | |
| + 
 | |
| + 	switch (type) {
 | |
| + 	case RTM_DELNEIGH:
 | |
| + 		call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_DEVICE,
 | |
| +-					 fdb->dst->dev, &info.info, NULL);
 | |
| ++					 dev, &info.info, NULL);
 | |
| + 		break;
 | |
| + 	case RTM_NEWNEIGH:
 | |
| + 		call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_DEVICE,
 | |
| +-					 fdb->dst->dev, &info.info, NULL);
 | |
| ++					 dev, &info.info, NULL);
 | |
| + 		break;
 | |
| + 	}
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch b/target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch
 | |
| new file mode 100644
 | |
| index 0000000000..c86a854212
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/765-net-dsa-Include-local-addresses-in-assisted-CPU-port.patch
 | |
| @@ -0,0 +1,36 @@
 | |
| +From dd082716b43a3684b2f473ae5d1e76d1c076d86d Mon Sep 17 00:00:00 2001
 | |
| +From: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Date: Sat, 16 Jan 2021 02:25:12 +0100
 | |
| +Subject: [PATCH] net: dsa: Include local addresses in assisted CPU port
 | |
| + learning
 | |
| +
 | |
| +Add local addresses (i.e. the ports' MAC addresses) to the hardware
 | |
| +FDB when assisted CPU port learning is enabled.
 | |
| +
 | |
| +NOTE: The bridge's own MAC address is also "local". If that address is
 | |
| +not shared with any port, the bridge's MAC is not be added by this
 | |
| +functionality - but the following commit takes care of that case.
 | |
| +
 | |
| +Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +---
 | |
| + net/dsa/slave.c | 8 +++++---
 | |
| + 1 file changed, 5 insertions(+), 3 deletions(-)
 | |
| +
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2189,10 +2189,12 @@ static int dsa_slave_switchdev_event(str
 | |
| + 		fdb_info = ptr;
 | |
| + 
 | |
| + 		if (dsa_slave_dev_check(dev)) {
 | |
| +-			if (!fdb_info->added_by_user)
 | |
| +-				return NOTIFY_OK;
 | |
| +-
 | |
| + 			dp = dsa_slave_to_port(dev);
 | |
| ++
 | |
| ++			if (fdb_info->local && dp->ds->assisted_learning_on_cpu_port)
 | |
| ++				dp = dp->cpu_dp;
 | |
| ++			else if (!fdb_info->added_by_user)
 | |
| ++				return NOTIFY_OK;
 | |
| + 		} else {
 | |
| + 			/* Snoop addresses learnt on foreign interfaces
 | |
| + 			 * bridged with us, for switches that don't
 | |
| diff --git a/target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch b/target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch
 | |
| new file mode 100644
 | |
| index 0000000000..bf356422de
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/766-net-dsa-Include-bridge-addresses-in-assisted-CPU-por.patch
 | |
| @@ -0,0 +1,30 @@
 | |
| +From 0663ebde114a6fb2c28c622ba5212b302d4d2581 Mon Sep 17 00:00:00 2001
 | |
| +From: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Date: Sat, 16 Jan 2021 02:25:13 +0100
 | |
| +Subject: [PATCH] net: dsa: Include bridge addresses in assisted CPU port
 | |
| + learning
 | |
| +
 | |
| +Now that notifications are sent out for addresses added to the bridge
 | |
| +itself, extend DSA to include those addresses in the hardware FDB when
 | |
| +assisted CPU port learning is enabled.
 | |
| +
 | |
| +Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +---
 | |
| + net/dsa/slave.c | 6 +++++-
 | |
| + 1 file changed, 5 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2203,7 +2203,11 @@ static int dsa_slave_switchdev_event(str
 | |
| + 			struct net_device *br_dev;
 | |
| + 			struct dsa_slave_priv *p;
 | |
| + 
 | |
| +-			br_dev = netdev_master_upper_dev_get_rcu(dev);
 | |
| ++			if (netif_is_bridge_master(dev))
 | |
| ++				br_dev = dev;
 | |
| ++			else
 | |
| ++				br_dev = netdev_master_upper_dev_get_rcu(dev);
 | |
| ++
 | |
| + 			if (!br_dev)
 | |
| + 				return NOTIFY_DONE;
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch b/target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch
 | |
| new file mode 100644
 | |
| index 0000000000..84ad38f6eb
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/767-net-dsa-Sync-static-FDB-entries-on-foreign-interface.patch
 | |
| @@ -0,0 +1,56 @@
 | |
| +From 81e39fd78db82fb51b05fff309b9c521f1a0bc5a Mon Sep 17 00:00:00 2001
 | |
| +From: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Date: Sat, 16 Jan 2021 02:25:14 +0100
 | |
| +Subject: [PATCH] net: dsa: Sync static FDB entries on foreign interfaces to
 | |
| + hardware
 | |
| +
 | |
| +Reuse the "assisted_learning_on_cpu_port" functionality to always add
 | |
| +entries for user-configured entries on foreign interfaces, even if
 | |
| +assisted_learning_on_cpu_port is not enabled. E.g. in this situation:
 | |
| +
 | |
| +   br0
 | |
| +   / \
 | |
| +swp0 dummy0
 | |
| +
 | |
| +$ bridge fdb add 02:00:de:ad:00:01 dev dummy0 vlan 1 master
 | |
| +
 | |
| +Results in DSA adding an entry in the hardware FDB, pointing this
 | |
| +address towards the CPU port.
 | |
| +
 | |
| +The same is true for entries added to the bridge itself, e.g:
 | |
| +
 | |
| +$ bridge fdb add 02:00:de:ad:00:01 dev br0 vlan 1 self
 | |
| +
 | |
| +Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +---
 | |
| + net/dsa/slave.c | 12 ++++++++----
 | |
| + 1 file changed, 8 insertions(+), 4 deletions(-)
 | |
| +
 | |
| +--- a/net/dsa/slave.c
 | |
| ++++ b/net/dsa/slave.c
 | |
| +@@ -2196,9 +2196,12 @@ static int dsa_slave_switchdev_event(str
 | |
| + 			else if (!fdb_info->added_by_user)
 | |
| + 				return NOTIFY_OK;
 | |
| + 		} else {
 | |
| +-			/* Snoop addresses learnt on foreign interfaces
 | |
| +-			 * bridged with us, for switches that don't
 | |
| +-			 * automatically learn SA from CPU-injected traffic
 | |
| ++			/* Snoop addresses added to foreign interfaces
 | |
| ++			 * bridged with us, or the bridge
 | |
| ++			 * itself. Dynamically learned addresses can
 | |
| ++			 * also be added for switches that don't
 | |
| ++			 * automatically learn SA from CPU-injected
 | |
| ++			 * traffic.
 | |
| + 			 */
 | |
| + 			struct net_device *br_dev;
 | |
| + 			struct dsa_slave_priv *p;
 | |
| +@@ -2220,7 +2223,8 @@ static int dsa_slave_switchdev_event(str
 | |
| + 
 | |
| + 			dp = p->dp->cpu_dp;
 | |
| + 
 | |
| +-			if (!dp->ds->assisted_learning_on_cpu_port)
 | |
| ++			if (!fdb_info->added_by_user &&
 | |
| ++			    !dp->ds->assisted_learning_on_cpu_port)
 | |
| + 				return NOTIFY_DONE;
 | |
| + 		}
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch b/target/linux/generic/pending-5.10/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
 | |
| new file mode 100644
 | |
| index 0000000000..5b8d058247
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/768-net-dsa-mv88e6xxx-Request-assisted-learning-on-CPU-port.patch
 | |
| @@ -0,0 +1,27 @@
 | |
| +From:   Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +Subject: [RFC net-next 7/7] net: dsa: mv88e6xxx: Request assisted learning on CPU port
 | |
| +Date:   Sat, 16 Jan 2021 02:25:15 +0100
 | |
| +Archived-At: <https://lore.kernel.org/netdev/20210116012515.3152-8-tobias@waldekranz.com/>
 | |
| +
 | |
| +While the hardware is capable of performing learning on the CPU port,
 | |
| +it requires alot of additions to the bridge's forwarding path in order
 | |
| +to handle multi-destination traffic correctly.
 | |
| +
 | |
| +Until that is in place, opt for the next best thing and let DSA sync
 | |
| +the relevant addresses down to the hardware FDB.
 | |
| +
 | |
| +Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
 | |
| +---
 | |
| + drivers/net/dsa/mv88e6xxx/chip.c | 1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| ++++ b/drivers/net/dsa/mv88e6xxx/chip.c
 | |
| +@@ -5405,6 +5405,7 @@ static int mv88e6xxx_register_switch(str
 | |
| + 	ds->ops = &mv88e6xxx_switch_ops;
 | |
| + 	ds->ageing_time_min = chip->info->age_time_coeff;
 | |
| + 	ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX;
 | |
| ++	ds->assisted_learning_on_cpu_port = true;
 | |
| + 
 | |
| + 	dev_set_drvdata(dev, ds);
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch b/target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch
 | |
| new file mode 100644
 | |
| index 0000000000..85c859b388
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-00-net-ethernet-mtk_eth_soc-use-napi_consume_skb.patch
 | |
| @@ -0,0 +1,72 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Mon, 8 Jun 2020 17:01:12 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: use napi_consume_skb
 | |
| +
 | |
| +Should improve performance, since it can use bulk free
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -857,7 +857,8 @@ static int txd_to_idx(struct mtk_tx_ring
 | |
| + 	return ((void *)dma - (void *)ring->dma) / sizeof(*dma);
 | |
| + }
 | |
| + 
 | |
| +-static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf)
 | |
| ++static void mtk_tx_unmap(struct mtk_eth *eth, struct mtk_tx_buf *tx_buf,
 | |
| ++			 bool napi)
 | |
| + {
 | |
| + 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
 | |
| + 		if (tx_buf->flags & MTK_TX_FLAGS_SINGLE0) {
 | |
| +@@ -889,8 +890,12 @@ static void mtk_tx_unmap(struct mtk_eth
 | |
| + 
 | |
| + 	tx_buf->flags = 0;
 | |
| + 	if (tx_buf->skb &&
 | |
| +-	    (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC))
 | |
| +-		dev_kfree_skb_any(tx_buf->skb);
 | |
| ++	    (tx_buf->skb != (struct sk_buff *)MTK_DMA_DUMMY_DESC)) {
 | |
| ++		if (napi)
 | |
| ++			napi_consume_skb(tx_buf->skb, napi);
 | |
| ++		else
 | |
| ++			dev_kfree_skb_any(tx_buf->skb);
 | |
| ++	}
 | |
| + 	tx_buf->skb = NULL;
 | |
| + }
 | |
| + 
 | |
| +@@ -1068,7 +1073,7 @@ err_dma:
 | |
| + 		tx_buf = mtk_desc_to_tx_buf(ring, itxd);
 | |
| + 
 | |
| + 		/* unmap dma */
 | |
| +-		mtk_tx_unmap(eth, tx_buf);
 | |
| ++		mtk_tx_unmap(eth, tx_buf, false);
 | |
| + 
 | |
| + 		itxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
 | |
| + 		if (!MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
 | |
| +@@ -1386,7 +1391,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
 | |
| + 			done[mac]++;
 | |
| + 			budget--;
 | |
| + 		}
 | |
| +-		mtk_tx_unmap(eth, tx_buf);
 | |
| ++		mtk_tx_unmap(eth, tx_buf, true);
 | |
| + 
 | |
| + 		ring->last_free = desc;
 | |
| + 		atomic_inc(&ring->free_count);
 | |
| +@@ -1423,7 +1428,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
 | |
| + 			budget--;
 | |
| + 		}
 | |
| + 
 | |
| +-		mtk_tx_unmap(eth, tx_buf);
 | |
| ++		mtk_tx_unmap(eth, tx_buf, true);
 | |
| + 
 | |
| + 		desc = &ring->dma[cpu];
 | |
| + 		ring->last_free = desc;
 | |
| +@@ -1625,7 +1630,7 @@ static void mtk_tx_clean(struct mtk_eth
 | |
| + 
 | |
| + 	if (ring->buf) {
 | |
| + 		for (i = 0; i < MTK_DMA_SIZE; i++)
 | |
| +-			mtk_tx_unmap(eth, &ring->buf[i]);
 | |
| ++			mtk_tx_unmap(eth, &ring->buf[i], false);
 | |
| + 		kfree(ring->buf);
 | |
| + 		ring->buf = NULL;
 | |
| + 	}
 | |
| diff --git a/target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch b/target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch
 | |
| new file mode 100644
 | |
| index 0000000000..922c35a3e4
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-01-net-ethernet-mtk_eth_soc-significantly-reduce-mdio-b.patch
 | |
| @@ -0,0 +1,26 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Mon, 8 Jun 2020 17:02:39 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: significantly reduce mdio bus
 | |
| + access latency
 | |
| +
 | |
| +usleep_range often ends up sleeping much longer than the 10-20us provided
 | |
| +as a range here. This causes significant latency in mdio bus acceses,
 | |
| +which easily adds multiple seconds to the boot time on MT7621 when polling
 | |
| +DSA slave ports.
 | |
| +Use cond_resched instead of usleep_range, since the MDIO access does not
 | |
| +take much time
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -85,7 +85,7 @@ static int mtk_mdio_busy_wait(struct mtk
 | |
| + 			return 0;
 | |
| + 		if (time_after(jiffies, t_start + PHY_IAC_TIMEOUT))
 | |
| + 			break;
 | |
| +-		usleep_range(10, 20);
 | |
| ++		cond_resched();
 | |
| + 	}
 | |
| + 
 | |
| + 	dev_err(eth->dev, "mdio: MDIO timeout\n");
 | |
| diff --git a/target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch b/target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch
 | |
| new file mode 100644
 | |
| index 0000000000..cebfe32d95
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-02-net-ethernet-mtk_eth_soc-fix-rx-vlan-offload.patch
 | |
| @@ -0,0 +1,31 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Wed, 26 Aug 2020 16:52:12 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix rx vlan offload
 | |
| +
 | |
| +The VLAN ID in the rx descriptor is only valid if the RX_DMA_VID bit is set
 | |
| +Fixes frames wrongly marked with VLAN tags
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -1324,7 +1324,7 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 		skb->protocol = eth_type_trans(skb, netdev);
 | |
| + 
 | |
| + 		if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
 | |
| +-		    RX_DMA_VID(trxd.rxd3))
 | |
| ++		    (trxd.rxd2 & RX_DMA_VTAG))
 | |
| + 			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
 | |
| + 					       RX_DMA_VID(trxd.rxd3));
 | |
| + 		skb_record_rx_queue(skb, 0);
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -295,6 +295,7 @@
 | |
| + #define RX_DMA_LSO		BIT(30)
 | |
| + #define RX_DMA_PLEN0(_x)	(((_x) & 0x3fff) << 16)
 | |
| + #define RX_DMA_GET_PLEN0(_x)	(((_x) >> 16) & 0x3fff)
 | |
| ++#define RX_DMA_VTAG		BIT(15)
 | |
| + 
 | |
| + /* QDMA descriptor rxd3 */
 | |
| + #define RX_DMA_VID(_x)		((_x) & 0xfff)
 | |
| diff --git a/target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch b/target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch
 | |
| new file mode 100644
 | |
| index 0000000000..82bdb10eba
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-03-net-ethernet-mtk_eth_soc-fix-unnecessary-tx-queue-st.patch
 | |
| @@ -0,0 +1,50 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Wed, 26 Aug 2020 16:55:54 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix unnecessary tx queue
 | |
| + stops
 | |
| +
 | |
| +When running short on descriptors, only stop the queue for the netdev that tx
 | |
| +was attempted for. By the time the something tries to send on the other netdev,
 | |
| +the ring might have some more room already
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -1130,17 +1130,6 @@ static void mtk_wake_queue(struct mtk_et
 | |
| + 	}
 | |
| + }
 | |
| + 
 | |
| +-static void mtk_stop_queue(struct mtk_eth *eth)
 | |
| +-{
 | |
| +-	int i;
 | |
| +-
 | |
| +-	for (i = 0; i < MTK_MAC_COUNT; i++) {
 | |
| +-		if (!eth->netdev[i])
 | |
| +-			continue;
 | |
| +-		netif_stop_queue(eth->netdev[i]);
 | |
| +-	}
 | |
| +-}
 | |
| +-
 | |
| + static netdev_tx_t mtk_start_xmit(struct sk_buff *skb, struct net_device *dev)
 | |
| + {
 | |
| + 	struct mtk_mac *mac = netdev_priv(dev);
 | |
| +@@ -1161,7 +1150,7 @@ static netdev_tx_t mtk_start_xmit(struct
 | |
| + 
 | |
| + 	tx_num = mtk_cal_txd_req(skb);
 | |
| + 	if (unlikely(atomic_read(&ring->free_count) <= tx_num)) {
 | |
| +-		mtk_stop_queue(eth);
 | |
| ++		netif_stop_queue(dev);
 | |
| + 		netif_err(eth, tx_queued, dev,
 | |
| + 			  "Tx Ring full when queue awake!\n");
 | |
| + 		spin_unlock(ð->page_lock);
 | |
| +@@ -1187,7 +1176,7 @@ static netdev_tx_t mtk_start_xmit(struct
 | |
| + 		goto drop;
 | |
| + 
 | |
| + 	if (unlikely(atomic_read(&ring->free_count) <= ring->thresh))
 | |
| +-		mtk_stop_queue(eth);
 | |
| ++		netif_stop_queue(dev);
 | |
| + 
 | |
| + 	spin_unlock(ð->page_lock);
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch b/target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch
 | |
| new file mode 100644
 | |
| index 0000000000..94c0510257
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-04-net-ethernet-mtk_eth_soc-use-larger-burst-size-for-q.patch
 | |
| @@ -0,0 +1,32 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Wed, 26 Aug 2020 16:58:55 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: use larger burst size for
 | |
| + qdma tx
 | |
| +
 | |
| +Improves tx performance
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -2191,7 +2191,7 @@ static int mtk_start_dma(struct mtk_eth
 | |
| + 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA)) {
 | |
| + 		mtk_w32(eth,
 | |
| + 			MTK_TX_WB_DDONE | MTK_TX_DMA_EN |
 | |
| +-			MTK_DMA_SIZE_16DWORDS | MTK_NDP_CO_PRO |
 | |
| ++			MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
 | |
| + 			MTK_RX_DMA_EN | MTK_RX_2B_OFFSET |
 | |
| + 			MTK_RX_BT_32DWORDS,
 | |
| + 			MTK_QDMA_GLO_CFG);
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -197,7 +197,7 @@
 | |
| + #define MTK_RX_BT_32DWORDS	(3 << 11)
 | |
| + #define MTK_NDP_CO_PRO		BIT(10)
 | |
| + #define MTK_TX_WB_DDONE		BIT(6)
 | |
| +-#define MTK_DMA_SIZE_16DWORDS	(2 << 4)
 | |
| ++#define MTK_TX_BT_32DWORDS	(3 << 4)
 | |
| + #define MTK_RX_DMA_BUSY		BIT(3)
 | |
| + #define MTK_TX_DMA_BUSY		BIT(1)
 | |
| + #define MTK_RX_DMA_EN		BIT(2)
 | |
| diff --git a/target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch b/target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch
 | |
| new file mode 100644
 | |
| index 0000000000..f68cbc333c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-05-net-ethernet-mtk_eth_soc-increase-DMA-ring-sizes.patch
 | |
| @@ -0,0 +1,21 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Wed, 26 Aug 2020 16:59:41 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: increase DMA ring sizes
 | |
| +
 | |
| +256 descriptors is not enough for multi-gigabit traffic under load on MT7622.
 | |
| +Bump it to 512 to improve performance
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -19,7 +19,7 @@
 | |
| + #define MTK_QDMA_PAGE_SIZE	2048
 | |
| + #define	MTK_MAX_RX_LENGTH	1536
 | |
| + #define MTK_TX_DMA_BUF_LEN	0x3fff
 | |
| +-#define MTK_DMA_SIZE		256
 | |
| ++#define MTK_DMA_SIZE		512
 | |
| + #define MTK_NAPI_WEIGHT		64
 | |
| + #define MTK_MAC_COUNT		2
 | |
| + #define MTK_RX_ETH_HLEN		(VLAN_ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)
 | |
| diff --git a/target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch b/target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch
 | |
| new file mode 100644
 | |
| index 0000000000..61a51ba33b
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-06-net-ethernet-mtk_eth_soc-implement-dynamic-interrupt.patch
 | |
| @@ -0,0 +1,281 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Wed, 26 Aug 2020 17:02:30 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: implement dynamic interrupt
 | |
| + moderation
 | |
| +
 | |
| +Reduces the number of interrupts under load
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/Kconfig
 | |
| ++++ b/drivers/net/ethernet/mediatek/Kconfig
 | |
| +@@ -10,6 +10,7 @@ if NET_VENDOR_MEDIATEK
 | |
| + config NET_MEDIATEK_SOC
 | |
| + 	tristate "MediaTek SoC Gigabit Ethernet support"
 | |
| + 	select PHYLINK
 | |
| ++	select DIMLIB
 | |
| + 	help
 | |
| + 	  This driver supports the gigabit ethernet MACs in the
 | |
| + 	  MediaTek SoC family.
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -1232,12 +1232,13 @@ static void mtk_update_rx_cpu_idx(struct
 | |
| + static int mtk_poll_rx(struct napi_struct *napi, int budget,
 | |
| + 		       struct mtk_eth *eth)
 | |
| + {
 | |
| ++	struct dim_sample dim_sample = {};
 | |
| + 	struct mtk_rx_ring *ring;
 | |
| + 	int idx;
 | |
| + 	struct sk_buff *skb;
 | |
| + 	u8 *data, *new_data;
 | |
| + 	struct mtk_rx_dma *rxd, trxd;
 | |
| +-	int done = 0;
 | |
| ++	int done = 0, bytes = 0;
 | |
| + 
 | |
| + 	while (done < budget) {
 | |
| + 		struct net_device *netdev;
 | |
| +@@ -1311,6 +1312,7 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 		else
 | |
| + 			skb_checksum_none_assert(skb);
 | |
| + 		skb->protocol = eth_type_trans(skb, netdev);
 | |
| ++		bytes += pktlen;
 | |
| + 
 | |
| + 		if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
 | |
| + 		    (trxd.rxd2 & RX_DMA_VTAG))
 | |
| +@@ -1342,6 +1344,12 @@ rx_done:
 | |
| + 		mtk_update_rx_cpu_idx(eth);
 | |
| + 	}
 | |
| + 
 | |
| ++	eth->rx_packets += done;
 | |
| ++	eth->rx_bytes += bytes;
 | |
| ++	dim_update_sample(eth->rx_events, eth->rx_packets, eth->rx_bytes,
 | |
| ++			  &dim_sample);
 | |
| ++	net_dim(ð->rx_dim, dim_sample);
 | |
| ++
 | |
| + 	return done;
 | |
| + }
 | |
| + 
 | |
| +@@ -1434,6 +1442,7 @@ static int mtk_poll_tx_pdma(struct mtk_e
 | |
| + static int mtk_poll_tx(struct mtk_eth *eth, int budget)
 | |
| + {
 | |
| + 	struct mtk_tx_ring *ring = ð->tx_ring;
 | |
| ++	struct dim_sample dim_sample = {};
 | |
| + 	unsigned int done[MTK_MAX_DEVS];
 | |
| + 	unsigned int bytes[MTK_MAX_DEVS];
 | |
| + 	int total = 0, i;
 | |
| +@@ -1451,8 +1460,14 @@ static int mtk_poll_tx(struct mtk_eth *e
 | |
| + 			continue;
 | |
| + 		netdev_completed_queue(eth->netdev[i], done[i], bytes[i]);
 | |
| + 		total += done[i];
 | |
| ++		eth->tx_packets += done[i];
 | |
| ++		eth->tx_bytes += bytes[i];
 | |
| + 	}
 | |
| + 
 | |
| ++	dim_update_sample(eth->tx_events, eth->tx_packets, eth->tx_bytes,
 | |
| ++			  &dim_sample);
 | |
| ++	net_dim(ð->tx_dim, dim_sample);
 | |
| ++
 | |
| + 	if (mtk_queue_stopped(eth) &&
 | |
| + 	    (atomic_read(&ring->free_count) > ring->thresh))
 | |
| + 		mtk_wake_queue(eth);
 | |
| +@@ -2127,6 +2142,7 @@ static irqreturn_t mtk_handle_irq_rx(int
 | |
| + {
 | |
| + 	struct mtk_eth *eth = _eth;
 | |
| + 
 | |
| ++	eth->rx_events++;
 | |
| + 	if (likely(napi_schedule_prep(ð->rx_napi))) {
 | |
| + 		__napi_schedule(ð->rx_napi);
 | |
| + 		mtk_rx_irq_disable(eth, MTK_RX_DONE_INT);
 | |
| +@@ -2139,6 +2155,7 @@ static irqreturn_t mtk_handle_irq_tx(int
 | |
| + {
 | |
| + 	struct mtk_eth *eth = _eth;
 | |
| + 
 | |
| ++	eth->tx_events++;
 | |
| + 	if (likely(napi_schedule_prep(ð->tx_napi))) {
 | |
| + 		__napi_schedule(ð->tx_napi);
 | |
| + 		mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
 | |
| +@@ -2315,6 +2332,9 @@ static int mtk_stop(struct net_device *d
 | |
| + 	napi_disable(ð->tx_napi);
 | |
| + 	napi_disable(ð->rx_napi);
 | |
| + 
 | |
| ++	cancel_work_sync(ð->rx_dim.work);
 | |
| ++	cancel_work_sync(ð->tx_dim.work);
 | |
| ++
 | |
| + 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
 | |
| + 		mtk_stop_dma(eth, MTK_QDMA_GLO_CFG);
 | |
| + 	mtk_stop_dma(eth, MTK_PDMA_GLO_CFG);
 | |
| +@@ -2364,6 +2384,64 @@ err_disable_clks:
 | |
| + 	return ret;
 | |
| + }
 | |
| + 
 | |
| ++static void mtk_dim_rx(struct work_struct *work)
 | |
| ++{
 | |
| ++	struct dim *dim = container_of(work, struct dim, work);
 | |
| ++	struct mtk_eth *eth = container_of(dim, struct mtk_eth, rx_dim);
 | |
| ++	struct dim_cq_moder cur_profile;
 | |
| ++	u32 val, cur;
 | |
| ++
 | |
| ++	cur_profile = net_dim_get_rx_moderation(eth->rx_dim.mode,
 | |
| ++						dim->profile_ix);
 | |
| ++	spin_lock_bh(ð->dim_lock);
 | |
| ++
 | |
| ++	val = mtk_r32(eth, MTK_PDMA_DELAY_INT);
 | |
| ++	val &= MTK_PDMA_DELAY_TX_MASK;
 | |
| ++	val |= MTK_PDMA_DELAY_RX_EN;
 | |
| ++
 | |
| ++	cur = min_t(u32, DIV_ROUND_UP(cur_profile.usec, 20), MTK_PDMA_DELAY_PTIME_MASK);
 | |
| ++	val |= cur << MTK_PDMA_DELAY_RX_PTIME_SHIFT;
 | |
| ++
 | |
| ++	cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK);
 | |
| ++	val |= cur << MTK_PDMA_DELAY_RX_PINT_SHIFT;
 | |
| ++
 | |
| ++	mtk_w32(eth, val, MTK_PDMA_DELAY_INT);
 | |
| ++	mtk_w32(eth, val, MTK_QDMA_DELAY_INT);
 | |
| ++
 | |
| ++	spin_unlock_bh(ð->dim_lock);
 | |
| ++
 | |
| ++	dim->state = DIM_START_MEASURE;
 | |
| ++}
 | |
| ++
 | |
| ++static void mtk_dim_tx(struct work_struct *work)
 | |
| ++{
 | |
| ++	struct dim *dim = container_of(work, struct dim, work);
 | |
| ++	struct mtk_eth *eth = container_of(dim, struct mtk_eth, tx_dim);
 | |
| ++	struct dim_cq_moder cur_profile;
 | |
| ++	u32 val, cur;
 | |
| ++
 | |
| ++	cur_profile = net_dim_get_tx_moderation(eth->tx_dim.mode,
 | |
| ++						dim->profile_ix);
 | |
| ++	spin_lock_bh(ð->dim_lock);
 | |
| ++
 | |
| ++	val = mtk_r32(eth, MTK_PDMA_DELAY_INT);
 | |
| ++	val &= MTK_PDMA_DELAY_RX_MASK;
 | |
| ++	val |= MTK_PDMA_DELAY_TX_EN;
 | |
| ++
 | |
| ++	cur = min_t(u32, DIV_ROUND_UP(cur_profile.usec, 20), MTK_PDMA_DELAY_PTIME_MASK);
 | |
| ++	val |= cur << MTK_PDMA_DELAY_TX_PTIME_SHIFT;
 | |
| ++
 | |
| ++	cur = min_t(u32, cur_profile.pkts, MTK_PDMA_DELAY_PINT_MASK);
 | |
| ++	val |= cur << MTK_PDMA_DELAY_TX_PINT_SHIFT;
 | |
| ++
 | |
| ++	mtk_w32(eth, val, MTK_PDMA_DELAY_INT);
 | |
| ++	mtk_w32(eth, val, MTK_QDMA_DELAY_INT);
 | |
| ++
 | |
| ++	spin_unlock_bh(ð->dim_lock);
 | |
| ++
 | |
| ++	dim->state = DIM_START_MEASURE;
 | |
| ++}
 | |
| ++
 | |
| + static int mtk_hw_init(struct mtk_eth *eth)
 | |
| + {
 | |
| + 	int i, val, ret;
 | |
| +@@ -2385,9 +2463,6 @@ static int mtk_hw_init(struct mtk_eth *e
 | |
| + 			goto err_disable_pm;
 | |
| + 		}
 | |
| + 
 | |
| +-		/* enable interrupt delay for RX */
 | |
| +-		mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_PDMA_DELAY_INT);
 | |
| +-
 | |
| + 		/* disable delay and normal interrupt */
 | |
| + 		mtk_tx_irq_disable(eth, ~0);
 | |
| + 		mtk_rx_irq_disable(eth, ~0);
 | |
| +@@ -2426,11 +2501,10 @@ static int mtk_hw_init(struct mtk_eth *e
 | |
| + 	/* Enable RX VLan Offloading */
 | |
| + 	mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
 | |
| + 
 | |
| +-	/* enable interrupt delay for RX */
 | |
| +-	mtk_w32(eth, MTK_PDMA_DELAY_RX_DELAY, MTK_PDMA_DELAY_INT);
 | |
| ++	mtk_dim_rx(ð->rx_dim.work);
 | |
| ++	mtk_dim_tx(ð->tx_dim.work);
 | |
| + 
 | |
| + 	/* disable delay and normal interrupt */
 | |
| +-	mtk_w32(eth, 0, MTK_QDMA_DELAY_INT);
 | |
| + 	mtk_tx_irq_disable(eth, ~0);
 | |
| + 	mtk_rx_irq_disable(eth, ~0);
 | |
| + 
 | |
| +@@ -2934,6 +3008,13 @@ static int mtk_probe(struct platform_dev
 | |
| + 	spin_lock_init(ð->page_lock);
 | |
| + 	spin_lock_init(ð->tx_irq_lock);
 | |
| + 	spin_lock_init(ð->rx_irq_lock);
 | |
| ++	spin_lock_init(ð->dim_lock);
 | |
| ++
 | |
| ++	eth->rx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 | |
| ++	INIT_WORK(ð->rx_dim.work, mtk_dim_rx);
 | |
| ++
 | |
| ++	eth->tx_dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 | |
| ++	INIT_WORK(ð->tx_dim.work, mtk_dim_tx);
 | |
| + 
 | |
| + 	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
 | |
| + 		eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -15,6 +15,7 @@
 | |
| + #include <linux/u64_stats_sync.h>
 | |
| + #include <linux/refcount.h>
 | |
| + #include <linux/phylink.h>
 | |
| ++#include <linux/dim.h>
 | |
| + 
 | |
| + #define MTK_QDMA_PAGE_SIZE	2048
 | |
| + #define	MTK_MAX_RX_LENGTH	1536
 | |
| +@@ -131,13 +132,18 @@
 | |
| + 
 | |
| + /* PDMA Delay Interrupt Register */
 | |
| + #define MTK_PDMA_DELAY_INT		0xa0c
 | |
| ++#define MTK_PDMA_DELAY_RX_MASK		GENMASK(15, 0)
 | |
| + #define MTK_PDMA_DELAY_RX_EN		BIT(15)
 | |
| +-#define MTK_PDMA_DELAY_RX_PINT		4
 | |
| + #define MTK_PDMA_DELAY_RX_PINT_SHIFT	8
 | |
| +-#define MTK_PDMA_DELAY_RX_PTIME		4
 | |
| +-#define MTK_PDMA_DELAY_RX_DELAY		\
 | |
| +-	(MTK_PDMA_DELAY_RX_EN | MTK_PDMA_DELAY_RX_PTIME | \
 | |
| +-	(MTK_PDMA_DELAY_RX_PINT << MTK_PDMA_DELAY_RX_PINT_SHIFT))
 | |
| ++#define MTK_PDMA_DELAY_RX_PTIME_SHIFT	0
 | |
| ++
 | |
| ++#define MTK_PDMA_DELAY_TX_MASK		GENMASK(31, 16)
 | |
| ++#define MTK_PDMA_DELAY_TX_EN		BIT(31)
 | |
| ++#define MTK_PDMA_DELAY_TX_PINT_SHIFT	24
 | |
| ++#define MTK_PDMA_DELAY_TX_PTIME_SHIFT	16
 | |
| ++
 | |
| ++#define MTK_PDMA_DELAY_PINT_MASK	0x7f
 | |
| ++#define MTK_PDMA_DELAY_PTIME_MASK	0xff
 | |
| + 
 | |
| + /* PDMA Interrupt Status Register */
 | |
| + #define MTK_PDMA_INT_STATUS	0xa20
 | |
| +@@ -219,6 +225,7 @@
 | |
| + /* QDMA Interrupt Status Register */
 | |
| + #define MTK_QDMA_INT_STATUS	0x1A18
 | |
| + #define MTK_RX_DONE_DLY		BIT(30)
 | |
| ++#define MTK_TX_DONE_DLY		BIT(28)
 | |
| + #define MTK_RX_DONE_INT3	BIT(19)
 | |
| + #define MTK_RX_DONE_INT2	BIT(18)
 | |
| + #define MTK_RX_DONE_INT1	BIT(17)
 | |
| +@@ -228,8 +235,7 @@
 | |
| + #define MTK_TX_DONE_INT1	BIT(1)
 | |
| + #define MTK_TX_DONE_INT0	BIT(0)
 | |
| + #define MTK_RX_DONE_INT		MTK_RX_DONE_DLY
 | |
| +-#define MTK_TX_DONE_INT		(MTK_TX_DONE_INT0 | MTK_TX_DONE_INT1 | \
 | |
| +-				 MTK_TX_DONE_INT2 | MTK_TX_DONE_INT3)
 | |
| ++#define MTK_TX_DONE_INT		MTK_TX_DONE_DLY
 | |
| + 
 | |
| + /* QDMA Interrupt grouping registers */
 | |
| + #define MTK_QDMA_INT_GRP1	0x1a20
 | |
| +@@ -892,6 +898,18 @@ struct mtk_eth {
 | |
| + 
 | |
| + 	const struct mtk_soc_data	*soc;
 | |
| + 
 | |
| ++	spinlock_t			dim_lock;
 | |
| ++
 | |
| ++	u32				rx_events;
 | |
| ++	u32				rx_packets;
 | |
| ++	u32				rx_bytes;
 | |
| ++	struct dim			rx_dim;
 | |
| ++
 | |
| ++	u32				tx_events;
 | |
| ++	u32				tx_packets;
 | |
| ++	u32				tx_bytes;
 | |
| ++	struct dim			tx_dim;
 | |
| ++
 | |
| + 	u32				tx_int_mask_reg;
 | |
| + 	u32				tx_int_status_reg;
 | |
| + 	u32				rx_dma_l4_valid;
 | |
| diff --git a/target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch b/target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch
 | |
| new file mode 100644
 | |
| index 0000000000..20181b8d12
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-08-net-ethernet-mtk_eth_soc-cache-hardware-pointer-of-l.patch
 | |
| @@ -0,0 +1,67 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Thu, 27 Aug 2020 06:32:03 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: cache hardware pointer of last
 | |
| + freed tx descriptor
 | |
| +
 | |
| +The value is only updated by the CPU, so it is cheaper to access from the ring
 | |
| +data structure than from a hardware register
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -1362,7 +1362,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
 | |
| + 	struct mtk_tx_buf *tx_buf;
 | |
| + 	u32 cpu, dma;
 | |
| + 
 | |
| +-	cpu = mtk_r32(eth, MTK_QTX_CRX_PTR);
 | |
| ++	cpu = ring->last_free_ptr;
 | |
| + 	dma = mtk_r32(eth, MTK_QTX_DRX_PTR);
 | |
| + 
 | |
| + 	desc = mtk_qdma_phys_to_virt(ring, cpu);
 | |
| +@@ -1396,6 +1396,7 @@ static int mtk_poll_tx_qdma(struct mtk_e
 | |
| + 		cpu = next_cpu;
 | |
| + 	}
 | |
| + 
 | |
| ++	ring->last_free_ptr = cpu;
 | |
| + 	mtk_w32(eth, cpu, MTK_QTX_CRX_PTR);
 | |
| + 
 | |
| + 	return budget;
 | |
| +@@ -1596,6 +1597,7 @@ static int mtk_tx_alloc(struct mtk_eth *
 | |
| + 	atomic_set(&ring->free_count, MTK_DMA_SIZE - 2);
 | |
| + 	ring->next_free = &ring->dma[0];
 | |
| + 	ring->last_free = &ring->dma[MTK_DMA_SIZE - 1];
 | |
| ++	ring->last_free_ptr = (u32)(ring->phys + ((MTK_DMA_SIZE - 1) * sz));
 | |
| + 	ring->thresh = MAX_SKB_FRAGS;
 | |
| + 
 | |
| + 	/* make sure that all changes to the dma ring are flushed before we
 | |
| +@@ -1609,9 +1611,7 @@ static int mtk_tx_alloc(struct mtk_eth *
 | |
| + 		mtk_w32(eth,
 | |
| + 			ring->phys + ((MTK_DMA_SIZE - 1) * sz),
 | |
| + 			MTK_QTX_CRX_PTR);
 | |
| +-		mtk_w32(eth,
 | |
| +-			ring->phys + ((MTK_DMA_SIZE - 1) * sz),
 | |
| +-			MTK_QTX_DRX_PTR);
 | |
| ++		mtk_w32(eth, ring->last_free_ptr, MTK_QTX_DRX_PTR);
 | |
| + 		mtk_w32(eth, (QDMA_RES_THRES << 8) | QDMA_RES_THRES,
 | |
| + 			MTK_QTX_CFG(0));
 | |
| + 	} else {
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -624,6 +624,7 @@ struct mtk_tx_buf {
 | |
| +  * @phys:		The physical addr of tx_buf
 | |
| +  * @next_free:		Pointer to the next free descriptor
 | |
| +  * @last_free:		Pointer to the last free descriptor
 | |
| ++ * @last_free_ptr:	Hardware pointer value of the last free descriptor
 | |
| +  * @thresh:		The threshold of minimum amount of free descriptors
 | |
| +  * @free_count:		QDMA uses a linked list. Track how many free descriptors
 | |
| +  *			are present
 | |
| +@@ -634,6 +635,7 @@ struct mtk_tx_ring {
 | |
| + 	dma_addr_t phys;
 | |
| + 	struct mtk_tx_dma *next_free;
 | |
| + 	struct mtk_tx_dma *last_free;
 | |
| ++	u32 last_free_ptr;
 | |
| + 	u16 thresh;
 | |
| + 	atomic_t free_count;
 | |
| + 	int dma_size;
 | |
| diff --git a/target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch b/target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch
 | |
| new file mode 100644
 | |
| index 0000000000..bbd8ae7be4
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-09-net-ethernet-mtk_eth_soc-only-read-the-full-rx-descr.patch
 | |
| @@ -0,0 +1,44 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Thu, 27 Aug 2020 09:24:25 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: only read the full rx
 | |
| + descriptor if DMA is done
 | |
| +
 | |
| +Uncached memory access is expensive, and there is no need to access all
 | |
| +descriptor words if we can't process them anyway
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -776,13 +776,18 @@ static inline int mtk_max_buf_size(int f
 | |
| + 	return buf_size;
 | |
| + }
 | |
| + 
 | |
| +-static inline void mtk_rx_get_desc(struct mtk_rx_dma *rxd,
 | |
| ++static inline bool mtk_rx_get_desc(struct mtk_rx_dma *rxd,
 | |
| + 				   struct mtk_rx_dma *dma_rxd)
 | |
| + {
 | |
| +-	rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
 | |
| + 	rxd->rxd2 = READ_ONCE(dma_rxd->rxd2);
 | |
| ++	if (!(rxd->rxd2 & RX_DMA_DONE))
 | |
| ++		return false;
 | |
| ++
 | |
| ++	rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
 | |
| + 	rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
 | |
| + 	rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
 | |
| ++
 | |
| ++	return true;
 | |
| + }
 | |
| + 
 | |
| + /* the qdma core needs scratch memory to be setup */
 | |
| +@@ -1254,8 +1259,7 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 		rxd = &ring->dma[idx];
 | |
| + 		data = ring->data[idx];
 | |
| + 
 | |
| +-		mtk_rx_get_desc(&trxd, rxd);
 | |
| +-		if (!(trxd.rxd2 & RX_DMA_DONE))
 | |
| ++		if (!mtk_rx_get_desc(&trxd, rxd))
 | |
| + 			break;
 | |
| + 
 | |
| + 		/* find out which mac the packet come from. values start at 1 */
 | |
| diff --git a/target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch b/target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4a19fa1164
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-10-net-ethernet-mtk_eth_soc-unmap-rx-data-before-callin.patch
 | |
| @@ -0,0 +1,44 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Thu, 27 Aug 2020 09:44:43 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: unmap rx data before calling
 | |
| + build_skb
 | |
| +
 | |
| +Since build_skb accesses the data area (for initializing shinfo), dma unmap
 | |
| +needs to happen before that call
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -1297,17 +1297,18 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 			goto release_desc;
 | |
| + 		}
 | |
| + 
 | |
| ++		dma_unmap_single(eth->dev, trxd.rxd1,
 | |
| ++				 ring->buf_size, DMA_FROM_DEVICE);
 | |
| ++
 | |
| + 		/* receive data */
 | |
| + 		skb = build_skb(data, ring->frag_size);
 | |
| + 		if (unlikely(!skb)) {
 | |
| +-			skb_free_frag(new_data);
 | |
| ++			skb_free_frag(data);
 | |
| + 			netdev->stats.rx_dropped++;
 | |
| +-			goto release_desc;
 | |
| ++			goto skip_rx;
 | |
| + 		}
 | |
| + 		skb_reserve(skb, NET_SKB_PAD + NET_IP_ALIGN);
 | |
| + 
 | |
| +-		dma_unmap_single(eth->dev, trxd.rxd1,
 | |
| +-				 ring->buf_size, DMA_FROM_DEVICE);
 | |
| + 		pktlen = RX_DMA_GET_PLEN0(trxd.rxd2);
 | |
| + 		skb->dev = netdev;
 | |
| + 		skb_put(skb, pktlen);
 | |
| +@@ -1325,6 +1326,7 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 		skb_record_rx_queue(skb, 0);
 | |
| + 		napi_gro_receive(napi, skb);
 | |
| + 
 | |
| ++skip_rx:
 | |
| + 		ring->data[idx] = new_data;
 | |
| + 		rxd->rxd1 = (unsigned int)dma_addr;
 | |
| + 
 | |
| diff --git a/target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch b/target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch
 | |
| new file mode 100644
 | |
| index 0000000000..4c61951d77
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-11-net-ethernet-mtk_eth_soc-avoid-rearming-interrupt-if.patch
 | |
| @@ -0,0 +1,35 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Fri, 4 Sep 2020 18:14:05 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: avoid rearming interrupt if
 | |
| + napi_complete returns false
 | |
| +
 | |
| +Reduces unnecessary interrupts
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -1519,8 +1519,8 @@ static int mtk_napi_tx(struct napi_struc
 | |
| + 	if (status & MTK_TX_DONE_INT)
 | |
| + 		return budget;
 | |
| + 
 | |
| +-	napi_complete(napi);
 | |
| +-	mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
 | |
| ++	if (napi_complete(napi))
 | |
| ++		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
 | |
| + 
 | |
| + 	return tx_done;
 | |
| + }
 | |
| +@@ -1553,8 +1553,9 @@ poll_again:
 | |
| + 		remain_budget -= rx_done;
 | |
| + 		goto poll_again;
 | |
| + 	}
 | |
| +-	napi_complete(napi);
 | |
| +-	mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
 | |
| ++
 | |
| ++	if (napi_complete(napi))
 | |
| ++		mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
 | |
| + 
 | |
| + 	return rx_done + budget - remain_budget;
 | |
| + }
 | |
| diff --git a/target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch b/target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch
 | |
| new file mode 100644
 | |
| index 0000000000..d81d4bf5f4
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-13-net-ethernet-mtk_eth_soc-fix-parsing-packets-in-GDM.patch
 | |
| @@ -0,0 +1,67 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sun, 13 Sep 2020 08:17:02 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: fix parsing packets in GDM
 | |
| +
 | |
| +When using DSA, set the special tag in GDM ingress control to allow the MAC
 | |
| +to parse packets properly earlier. This affects rx DMA source port reporting.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -19,6 +19,7 @@
 | |
| + #include <linux/interrupt.h>
 | |
| + #include <linux/pinctrl/devinfo.h>
 | |
| + #include <linux/phylink.h>
 | |
| ++#include <net/dsa.h>
 | |
| + 
 | |
| + #include "mtk_eth_soc.h"
 | |
| + 
 | |
| +@@ -1263,13 +1264,12 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 			break;
 | |
| + 
 | |
| + 		/* find out which mac the packet come from. values start at 1 */
 | |
| +-		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
 | |
| ++		if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) ||
 | |
| ++		    (trxd.rxd4 & RX_DMA_SPECIAL_TAG))
 | |
| + 			mac = 0;
 | |
| +-		} else {
 | |
| +-			mac = (trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
 | |
| +-				RX_DMA_FPORT_MASK;
 | |
| +-			mac--;
 | |
| +-		}
 | |
| ++		else
 | |
| ++			mac = ((trxd.rxd4 >> RX_DMA_FPORT_SHIFT) &
 | |
| ++			       RX_DMA_FPORT_MASK) - 1;
 | |
| + 
 | |
| + 		if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
 | |
| + 			     !eth->netdev[mac]))
 | |
| +@@ -2251,6 +2251,9 @@ static void mtk_gdm_config(struct mtk_et
 | |
| + 
 | |
| + 		val |= config;
 | |
| + 
 | |
| ++		if (!i && eth->netdev[0] && netdev_uses_dsa(eth->netdev[0]))
 | |
| ++			val |= MTK_GDMA_SPECIAL_TAG;
 | |
| ++
 | |
| + 		mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
 | |
| + 	}
 | |
| + 	/* Reset and enable PSE */
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -82,6 +82,7 @@
 | |
| + 
 | |
| + /* GDM Exgress Control Register */
 | |
| + #define MTK_GDMA_FWD_CFG(x)	(0x500 + (x * 0x1000))
 | |
| ++#define MTK_GDMA_SPECIAL_TAG	BIT(24)
 | |
| + #define MTK_GDMA_ICS_EN		BIT(22)
 | |
| + #define MTK_GDMA_TCS_EN		BIT(21)
 | |
| + #define MTK_GDMA_UCS_EN		BIT(20)
 | |
| +@@ -311,6 +312,7 @@
 | |
| + #define RX_DMA_L4_VALID_PDMA	BIT(30)		/* when PDMA is used */
 | |
| + #define RX_DMA_FPORT_SHIFT	19
 | |
| + #define RX_DMA_FPORT_MASK	0x7
 | |
| ++#define RX_DMA_SPECIAL_TAG	BIT(22)
 | |
| + 
 | |
| + /* PHY Indirect Access Control registers */
 | |
| + #define MTK_PHY_IAC		0x10004
 | |
| diff --git a/target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch b/target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch
 | |
| new file mode 100644
 | |
| index 0000000000..e94b352b9c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-14-net-ethernet-mtk_eth_soc-set-PPE-flow-hash-as-skb-ha.patch
 | |
| @@ -0,0 +1,41 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sun, 13 Sep 2020 08:27:24 +0200
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: set PPE flow hash as skb hash
 | |
| + if present
 | |
| +
 | |
| +This improves GRO performance
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -19,6 +19,7 @@
 | |
| + #include <linux/interrupt.h>
 | |
| + #include <linux/pinctrl/devinfo.h>
 | |
| + #include <linux/phylink.h>
 | |
| ++#include <linux/jhash.h>
 | |
| + #include <net/dsa.h>
 | |
| + 
 | |
| + #include "mtk_eth_soc.h"
 | |
| +@@ -1250,6 +1251,7 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 		struct net_device *netdev;
 | |
| + 		unsigned int pktlen;
 | |
| + 		dma_addr_t dma_addr;
 | |
| ++		u32 hash;
 | |
| + 		int mac;
 | |
| + 
 | |
| + 		ring = mtk_get_rx_ring(eth);
 | |
| +@@ -1319,6 +1321,12 @@ static int mtk_poll_rx(struct napi_struc
 | |
| + 		skb->protocol = eth_type_trans(skb, netdev);
 | |
| + 		bytes += pktlen;
 | |
| + 
 | |
| ++		hash = trxd.rxd4 & GENMASK(13, 0);
 | |
| ++		if (hash != GENMASK(13, 0)) {
 | |
| ++			hash = jhash_1word(hash, 0);
 | |
| ++			skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
 | |
| ++		}
 | |
| ++
 | |
| + 		if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
 | |
| + 		    (trxd.rxd2 & RX_DMA_VTAG))
 | |
| + 			__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
 | |
| diff --git a/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch b/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch
 | |
| new file mode 100644
 | |
| index 0000000000..09282175b0
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-15-net-ethernet-mtk_eth_soc-add-support-for-initializin.patch
 | |
| @@ -0,0 +1,1307 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Sun, 11 Oct 2020 22:23:08 +0200
 | |
| +Subject: [PATCH] ethernet: mediatek: mtk_eth_soc: add support for
 | |
| + initializing the PPE
 | |
| +
 | |
| +The PPE (packet processing engine) is used to offload NAT/routed or even
 | |
| +bridged flows. This patch brings up the PPE and uses it to get a packet
 | |
| +hash. It also contains some functionality that will be used to bring up
 | |
| +flow offloading.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe.c
 | |
| + create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe.h
 | |
| + create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
 | |
| + create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe_regs.h
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/Makefile
 | |
| ++++ b/drivers/net/ethernet/mediatek/Makefile
 | |
| +@@ -4,5 +4,5 @@
 | |
| + #
 | |
| + 
 | |
| + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
 | |
| +-mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o
 | |
| ++mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o
 | |
| + obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -2284,12 +2284,17 @@ static int mtk_open(struct net_device *d
 | |
| + 
 | |
| + 	/* we run 2 netdevs on the same dma ring so we only bring it up once */
 | |
| + 	if (!refcount_read(ð->dma_refcnt)) {
 | |
| +-		int err = mtk_start_dma(eth);
 | |
| ++		u32 gdm_config = MTK_GDMA_TO_PDMA;
 | |
| ++		int err;
 | |
| + 
 | |
| ++		err = mtk_start_dma(eth);
 | |
| + 		if (err)
 | |
| + 			return err;
 | |
| + 
 | |
| +-		mtk_gdm_config(eth, MTK_GDMA_TO_PDMA);
 | |
| ++		if (eth->soc->offload_version && mtk_ppe_start(ð->ppe) == 0)
 | |
| ++			gdm_config = MTK_GDMA_TO_PPE;
 | |
| ++
 | |
| ++		mtk_gdm_config(eth, gdm_config);
 | |
| + 
 | |
| + 		napi_enable(ð->tx_napi);
 | |
| + 		napi_enable(ð->rx_napi);
 | |
| +@@ -2359,6 +2364,9 @@ static int mtk_stop(struct net_device *d
 | |
| + 
 | |
| + 	mtk_dma_free(eth);
 | |
| + 
 | |
| ++	if (eth->soc->offload_version)
 | |
| ++		mtk_ppe_stop(ð->ppe);
 | |
| ++
 | |
| + 	return 0;
 | |
| + }
 | |
| + 
 | |
| +@@ -3148,6 +3156,13 @@ static int mtk_probe(struct platform_dev
 | |
| + 			goto err_free_dev;
 | |
| + 	}
 | |
| + 
 | |
| ++	if (eth->soc->offload_version) {
 | |
| ++		err = mtk_ppe_init(ð->ppe, eth->dev,
 | |
| ++				   eth->base + MTK_ETH_PPE_BASE, 2);
 | |
| ++		if (err)
 | |
| ++			goto err_free_dev;
 | |
| ++	}
 | |
| ++
 | |
| + 	for (i = 0; i < MTK_MAX_DEVS; i++) {
 | |
| + 		if (!eth->netdev[i])
 | |
| + 			continue;
 | |
| +@@ -3222,6 +3237,7 @@ static const struct mtk_soc_data mt7621_
 | |
| + 	.hw_features = MTK_HW_FEATURES,
 | |
| + 	.required_clks = MT7621_CLKS_BITMAP,
 | |
| + 	.required_pctl = false,
 | |
| ++	.offload_version = 2,
 | |
| + };
 | |
| + 
 | |
| + static const struct mtk_soc_data mt7622_data = {
 | |
| +@@ -3230,6 +3246,7 @@ static const struct mtk_soc_data mt7622_
 | |
| + 	.hw_features = MTK_HW_FEATURES,
 | |
| + 	.required_clks = MT7622_CLKS_BITMAP,
 | |
| + 	.required_pctl = false,
 | |
| ++	.offload_version = 2,
 | |
| + };
 | |
| + 
 | |
| + static const struct mtk_soc_data mt7623_data = {
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -16,6 +16,7 @@
 | |
| + #include <linux/refcount.h>
 | |
| + #include <linux/phylink.h>
 | |
| + #include <linux/dim.h>
 | |
| ++#include "mtk_ppe.h"
 | |
| + 
 | |
| + #define MTK_QDMA_PAGE_SIZE	2048
 | |
| + #define	MTK_MAX_RX_LENGTH	1536
 | |
| +@@ -87,6 +88,7 @@
 | |
| + #define MTK_GDMA_TCS_EN		BIT(21)
 | |
| + #define MTK_GDMA_UCS_EN		BIT(20)
 | |
| + #define MTK_GDMA_TO_PDMA	0x0
 | |
| ++#define MTK_GDMA_TO_PPE		0x4444
 | |
| + #define MTK_GDMA_DROP_ALL       0x7777
 | |
| + 
 | |
| + /* Unicast Filter MAC Address Register - Low */
 | |
| +@@ -308,6 +310,12 @@
 | |
| + #define RX_DMA_VID(_x)		((_x) & 0xfff)
 | |
| + 
 | |
| + /* QDMA descriptor rxd4 */
 | |
| ++#define MTK_RXD4_FOE_ENTRY	GENMASK(13, 0)
 | |
| ++#define MTK_RXD4_PPE_CPU_REASON	GENMASK(18, 14)
 | |
| ++#define MTK_RXD4_SRC_PORT	GENMASK(21, 19)
 | |
| ++#define MTK_RXD4_ALG		GENMASK(31, 22)
 | |
| ++
 | |
| ++/* QDMA descriptor rxd4 */
 | |
| + #define RX_DMA_L4_VALID		BIT(24)
 | |
| + #define RX_DMA_L4_VALID_PDMA	BIT(30)		/* when PDMA is used */
 | |
| + #define RX_DMA_FPORT_SHIFT	19
 | |
| +@@ -807,6 +815,7 @@ struct mtk_soc_data {
 | |
| + 	u32		caps;
 | |
| + 	u32		required_clks;
 | |
| + 	bool		required_pctl;
 | |
| ++	u8		offload_version;
 | |
| + 	netdev_features_t hw_features;
 | |
| + };
 | |
| + 
 | |
| +@@ -918,6 +927,8 @@ struct mtk_eth {
 | |
| + 	u32				tx_int_status_reg;
 | |
| + 	u32				rx_dma_l4_valid;
 | |
| + 	int				ip_align;
 | |
| ++
 | |
| ++	struct mtk_ppe			ppe;
 | |
| + };
 | |
| + 
 | |
| + /* struct mtk_mac -	the structure that holds the info about the MACs of the
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
 | |
| +@@ -0,0 +1,511 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0-only
 | |
| ++/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
 | |
| ++
 | |
| ++#include <linux/kernel.h>
 | |
| ++#include <linux/jiffies.h>
 | |
| ++#include <linux/delay.h>
 | |
| ++#include <linux/io.h>
 | |
| ++#include <linux/etherdevice.h>
 | |
| ++#include <linux/platform_device.h>
 | |
| ++#include "mtk_ppe.h"
 | |
| ++#include "mtk_ppe_regs.h"
 | |
| ++
 | |
| ++static void ppe_w32(struct mtk_ppe *ppe, u32 reg, u32 val)
 | |
| ++{
 | |
| ++	writel(val, ppe->base + reg);
 | |
| ++}
 | |
| ++
 | |
| ++static u32 ppe_r32(struct mtk_ppe *ppe, u32 reg)
 | |
| ++{
 | |
| ++	return readl(ppe->base + reg);
 | |
| ++}
 | |
| ++
 | |
| ++static u32 ppe_m32(struct mtk_ppe *ppe, u32 reg, u32 mask, u32 set)
 | |
| ++{
 | |
| ++	u32 val;
 | |
| ++
 | |
| ++	val = ppe_r32(ppe, reg);
 | |
| ++	val &= ~mask;
 | |
| ++	val |= set;
 | |
| ++	ppe_w32(ppe, reg, val);
 | |
| ++
 | |
| ++	return val;
 | |
| ++}
 | |
| ++
 | |
| ++static u32 ppe_set(struct mtk_ppe *ppe, u32 reg, u32 val)
 | |
| ++{
 | |
| ++	return ppe_m32(ppe, reg, 0, val);
 | |
| ++}
 | |
| ++
 | |
| ++static u32 ppe_clear(struct mtk_ppe *ppe, u32 reg, u32 val)
 | |
| ++{
 | |
| ++	return ppe_m32(ppe, reg, val, 0);
 | |
| ++}
 | |
| ++
 | |
| ++static int mtk_ppe_wait_busy(struct mtk_ppe *ppe)
 | |
| ++{
 | |
| ++	unsigned long timeout = jiffies + HZ;
 | |
| ++
 | |
| ++	while (time_is_after_jiffies(timeout)) {
 | |
| ++		if (!(ppe_r32(ppe, MTK_PPE_GLO_CFG) & MTK_PPE_GLO_CFG_BUSY))
 | |
| ++			return 0;
 | |
| ++
 | |
| ++		usleep_range(10, 20);
 | |
| ++	}
 | |
| ++
 | |
| ++	dev_err(ppe->dev, "PPE table busy");
 | |
| ++
 | |
| ++	return -ETIMEDOUT;
 | |
| ++}
 | |
| ++
 | |
| ++static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
 | |
| ++{
 | |
| ++	ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
 | |
| ++	ppe_clear(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
 | |
| ++}
 | |
| ++
 | |
| ++static void mtk_ppe_cache_enable(struct mtk_ppe *ppe, bool enable)
 | |
| ++{
 | |
| ++	mtk_ppe_cache_clear(ppe);
 | |
| ++
 | |
| ++	ppe_m32(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_EN,
 | |
| ++		enable * MTK_PPE_CACHE_CTL_EN);
 | |
| ++}
 | |
| ++
 | |
| ++static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
 | |
| ++{
 | |
| ++	u32 hv1, hv2, hv3;
 | |
| ++	u32 hash;
 | |
| ++
 | |
| ++	switch (FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, e->ib1)) {
 | |
| ++		case MTK_PPE_PKT_TYPE_BRIDGE:
 | |
| ++			hv1 = e->bridge.src_mac_lo;
 | |
| ++			hv1 ^= ((e->bridge.src_mac_hi & 0xffff) << 16);
 | |
| ++			hv2 = e->bridge.src_mac_hi >> 16;
 | |
| ++			hv2 ^= e->bridge.dest_mac_lo;
 | |
| ++			hv3 = e->bridge.dest_mac_hi;
 | |
| ++			break;
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
 | |
| ++			hv1 = e->ipv4.orig.ports;
 | |
| ++			hv2 = e->ipv4.orig.dest_ip;
 | |
| ++			hv3 = e->ipv4.orig.src_ip;
 | |
| ++			break;
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T:
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T:
 | |
| ++			hv1 = e->ipv6.src_ip[3] ^ e->ipv6.dest_ip[3];
 | |
| ++			hv1 ^= e->ipv6.ports;
 | |
| ++
 | |
| ++			hv2 = e->ipv6.src_ip[2] ^ e->ipv6.dest_ip[2];
 | |
| ++			hv2 ^= e->ipv6.dest_ip[0];
 | |
| ++
 | |
| ++			hv3 = e->ipv6.src_ip[1] ^ e->ipv6.dest_ip[1];
 | |
| ++			hv3 ^= e->ipv6.src_ip[0];
 | |
| ++			break;
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_DSLITE:
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV6_6RD:
 | |
| ++		default:
 | |
| ++			WARN_ON_ONCE(1);
 | |
| ++			return MTK_PPE_HASH_MASK;
 | |
| ++	}
 | |
| ++
 | |
| ++	hash = (hv1 & hv2) | ((~hv1) & hv3);
 | |
| ++	hash = (hash >> 24) | ((hash & 0xffffff) << 8);
 | |
| ++	hash ^= hv1 ^ hv2 ^ hv3;
 | |
| ++	hash ^= hash >> 16;
 | |
| ++	hash <<= 1;
 | |
| ++	hash &= MTK_PPE_ENTRIES - 1;
 | |
| ++
 | |
| ++	return hash;
 | |
| ++}
 | |
| ++
 | |
| ++static inline struct mtk_foe_mac_info *
 | |
| ++mtk_foe_entry_l2(struct mtk_foe_entry *entry)
 | |
| ++{
 | |
| ++	int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 | |
| ++
 | |
| ++	if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE)
 | |
| ++		return &entry->ipv6.l2;
 | |
| ++
 | |
| ++	return &entry->ipv4.l2;
 | |
| ++}
 | |
| ++
 | |
| ++static inline u32 *
 | |
| ++mtk_foe_entry_ib2(struct mtk_foe_entry *entry)
 | |
| ++{
 | |
| ++	int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 | |
| ++
 | |
| ++	if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE)
 | |
| ++		return &entry->ipv6.ib2;
 | |
| ++
 | |
| ++	return &entry->ipv4.ib2;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto,
 | |
| ++			  u8 pse_port, u8 *src_mac, u8 *dest_mac)
 | |
| ++{
 | |
| ++	struct mtk_foe_mac_info *l2;
 | |
| ++	u32 ports_pad, val;
 | |
| ++
 | |
| ++	memset(entry, 0, sizeof(*entry));
 | |
| ++
 | |
| ++	val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
 | |
| ++	      FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE, type) |
 | |
| ++	      FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
 | |
| ++	      MTK_FOE_IB1_BIND_TTL |
 | |
| ++	      MTK_FOE_IB1_BIND_CACHE;
 | |
| ++	entry->ib1 = val;
 | |
| ++
 | |
| ++	val = FIELD_PREP(MTK_FOE_IB2_PORT_MG, 0x3f) |
 | |
| ++	      FIELD_PREP(MTK_FOE_IB2_PORT_AG, 0x1f) |
 | |
| ++	      FIELD_PREP(MTK_FOE_IB2_DEST_PORT, pse_port);
 | |
| ++
 | |
| ++	if (is_multicast_ether_addr(dest_mac))
 | |
| ++		val |= MTK_FOE_IB2_MULTICAST;
 | |
| ++
 | |
| ++	ports_pad = 0xa5a5a500 | (l4proto & 0xff);
 | |
| ++	if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE)
 | |
| ++		entry->ipv4.orig.ports = ports_pad;
 | |
| ++	if (type == MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T)
 | |
| ++		entry->ipv6.ports = ports_pad;
 | |
| ++
 | |
| ++	if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) {
 | |
| ++		entry->ipv6.ib2 = val;
 | |
| ++		l2 = &entry->ipv6.l2;
 | |
| ++	} else {
 | |
| ++		entry->ipv4.ib2 = val;
 | |
| ++		l2 = &entry->ipv4.l2;
 | |
| ++	}
 | |
| ++
 | |
| ++	l2->dest_mac_hi = get_unaligned_be32(dest_mac);
 | |
| ++	l2->dest_mac_lo = get_unaligned_be16(dest_mac + 4);
 | |
| ++	l2->src_mac_hi = get_unaligned_be32(src_mac);
 | |
| ++	l2->src_mac_lo = get_unaligned_be16(src_mac + 4);
 | |
| ++
 | |
| ++	if (type >= MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T)
 | |
| ++		l2->etype = ETH_P_IPV6;
 | |
| ++	else
 | |
| ++		l2->etype = ETH_P_IP;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port)
 | |
| ++{
 | |
| ++	u32 *ib2 = mtk_foe_entry_ib2(entry);
 | |
| ++	u32 val;
 | |
| ++
 | |
| ++	val = *ib2;
 | |
| ++	val &= ~MTK_FOE_IB2_DEST_PORT;
 | |
| ++	val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT, port);
 | |
| ++	*ib2 = val;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool egress,
 | |
| ++				 __be32 src_addr, __be16 src_port,
 | |
| ++				 __be32 dest_addr, __be16 dest_port)
 | |
| ++{
 | |
| ++	int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 | |
| ++	struct mtk_ipv4_tuple *t;
 | |
| ++
 | |
| ++	switch (type) {
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
 | |
| ++		if (egress) {
 | |
| ++			t = &entry->ipv4.new;
 | |
| ++			break;
 | |
| ++		}
 | |
| ++		fallthrough;
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV4_DSLITE:
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
 | |
| ++		t = &entry->ipv4.orig;
 | |
| ++		break;
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV6_6RD:
 | |
| ++		entry->ipv6_6rd.tunnel_src_ip = be32_to_cpu(src_addr);
 | |
| ++		entry->ipv6_6rd.tunnel_dest_ip = be32_to_cpu(dest_addr);
 | |
| ++		return 0;
 | |
| ++	default:
 | |
| ++		WARN_ON_ONCE(1);
 | |
| ++		return -EINVAL;
 | |
| ++	}
 | |
| ++
 | |
| ++	t->src_ip = be32_to_cpu(src_addr);
 | |
| ++	t->dest_ip = be32_to_cpu(dest_addr);
 | |
| ++
 | |
| ++	if (type == MTK_PPE_PKT_TYPE_IPV4_ROUTE)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	t->src_port = be16_to_cpu(src_port);
 | |
| ++	t->dest_port = be16_to_cpu(dest_port);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry,
 | |
| ++				 __be32 *src_addr, __be16 src_port,
 | |
| ++				 __be32 *dest_addr, __be16 dest_port)
 | |
| ++{
 | |
| ++	int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 | |
| ++	u32 *src, *dest;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	switch (type) {
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV4_DSLITE:
 | |
| ++		src = entry->dslite.tunnel_src_ip;
 | |
| ++		dest = entry->dslite.tunnel_dest_ip;
 | |
| ++		break;
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T:
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV6_6RD:
 | |
| ++		entry->ipv6.src_port = be16_to_cpu(src_port);
 | |
| ++		entry->ipv6.dest_port = be16_to_cpu(dest_port);
 | |
| ++		fallthrough;
 | |
| ++	case MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T:
 | |
| ++		src = entry->ipv6.src_ip;
 | |
| ++		dest = entry->ipv6.dest_ip;
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		WARN_ON_ONCE(1);
 | |
| ++		return -EINVAL;
 | |
| ++	};
 | |
| ++
 | |
| ++	for (i = 0; i < 4; i++)
 | |
| ++		src[i] = be32_to_cpu(src_addr[i]);
 | |
| ++	for (i = 0; i < 4; i++)
 | |
| ++		dest[i] = be32_to_cpu(dest_addr[i]);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port)
 | |
| ++{
 | |
| ++	struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
 | |
| ++
 | |
| ++	l2->etype = BIT(port);
 | |
| ++
 | |
| ++	if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER))
 | |
| ++		entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1);
 | |
| ++	else
 | |
| ++		l2->etype |= BIT(8);
 | |
| ++
 | |
| ++	entry->ib1 &= ~MTK_FOE_IB1_BIND_VLAN_TAG;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid)
 | |
| ++{
 | |
| ++	struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
 | |
| ++
 | |
| ++	switch (FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, entry->ib1)) {
 | |
| ++	case 0:
 | |
| ++		entry->ib1 |= MTK_FOE_IB1_BIND_VLAN_TAG |
 | |
| ++			      FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1);
 | |
| ++		l2->vlan1 = vid;
 | |
| ++		return 0;
 | |
| ++	case 1:
 | |
| ++		if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG)) {
 | |
| ++			l2->vlan1 = vid;
 | |
| ++			l2->etype |= BIT(8);
 | |
| ++		} else {
 | |
| ++			l2->vlan2 = vid;
 | |
| ++			entry->ib1 += FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, 1);
 | |
| ++		}
 | |
| ++		return 0;
 | |
| ++	default:
 | |
| ++		return -ENOSPC;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid)
 | |
| ++{
 | |
| ++	struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(entry);
 | |
| ++
 | |
| ++	if (!(entry->ib1 & MTK_FOE_IB1_BIND_VLAN_LAYER) ||
 | |
| ++	    (entry->ib1 & MTK_FOE_IB1_BIND_VLAN_TAG))
 | |
| ++		l2->etype = ETH_P_PPP_SES;
 | |
| ++
 | |
| ++	entry->ib1 |= MTK_FOE_IB1_BIND_PPPOE;
 | |
| ++	l2->pppoe_id = sid;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static inline bool mtk_foe_entry_usable(struct mtk_foe_entry *entry)
 | |
| ++{
 | |
| ++	return !(entry->ib1 & MTK_FOE_IB1_STATIC) &&
 | |
| ++	       FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
 | |
| ++			 u16 timestamp)
 | |
| ++{
 | |
| ++	struct mtk_foe_entry *hwe;
 | |
| ++	u32 hash;
 | |
| ++
 | |
| ++	timestamp &= MTK_FOE_IB1_BIND_TIMESTAMP;
 | |
| ++	entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP;
 | |
| ++	entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP, timestamp);
 | |
| ++
 | |
| ++	hash = mtk_ppe_hash_entry(entry);
 | |
| ++	hwe = &ppe->foe_table[hash];
 | |
| ++	if (!mtk_foe_entry_usable(hwe)) {
 | |
| ++		hwe++;
 | |
| ++		hash++;
 | |
| ++
 | |
| ++		if (!mtk_foe_entry_usable(hwe))
 | |
| ++			return -ENOSPC;
 | |
| ++	}
 | |
| ++
 | |
| ++	memcpy(&hwe->data, &entry->data, sizeof(hwe->data));
 | |
| ++	wmb();
 | |
| ++	hwe->ib1 = entry->ib1;
 | |
| ++
 | |
| ++	dma_wmb();
 | |
| ++
 | |
| ++	mtk_ppe_cache_clear(ppe);
 | |
| ++
 | |
| ++	return hash;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
 | |
| ++		 int version)
 | |
| ++{
 | |
| ++	struct mtk_foe_entry *foe;
 | |
| ++
 | |
| ++	/* need to allocate a separate device, since it PPE DMA access is
 | |
| ++	 * not coherent.
 | |
| ++	 */
 | |
| ++	ppe->base = base;
 | |
| ++	ppe->dev = dev;
 | |
| ++	ppe->version = version;
 | |
| ++
 | |
| ++	foe = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*foe),
 | |
| ++				  &ppe->foe_phys, GFP_KERNEL);
 | |
| ++	if (!foe)
 | |
| ++		return -ENOMEM;
 | |
| ++
 | |
| ++	ppe->foe_table = foe;
 | |
| ++
 | |
| ++	mtk_ppe_debugfs_init(ppe);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
 | |
| ++{
 | |
| ++	static const u8 skip[] = { 12, 25, 38, 51, 76, 89, 102 };
 | |
| ++	int i, k;
 | |
| ++
 | |
| ++	memset(ppe->foe_table, 0, MTK_PPE_ENTRIES * sizeof(ppe->foe_table));
 | |
| ++
 | |
| ++	if (!IS_ENABLED(CONFIG_SOC_MT7621))
 | |
| ++		return;
 | |
| ++
 | |
| ++	/* skip all entries that cross the 1024 byte boundary */
 | |
| ++	for (i = 0; i < MTK_PPE_ENTRIES; i += 128)
 | |
| ++		for (k = 0; k < ARRAY_SIZE(skip); k++)
 | |
| ++			ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_ppe_start(struct mtk_ppe *ppe)
 | |
| ++{
 | |
| ++	u32 val;
 | |
| ++
 | |
| ++	mtk_ppe_init_foe_table(ppe);
 | |
| ++	ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
 | |
| ++
 | |
| ++	val = MTK_PPE_TB_CFG_ENTRY_80B |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_NON_L4 |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_UNBIND |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_TCP |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_UDP |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_TCP_FIN |
 | |
| ++	      FIELD_PREP(MTK_PPE_TB_CFG_SEARCH_MISS,
 | |
| ++			 MTK_PPE_SEARCH_MISS_ACTION_FORWARD_BUILD) |
 | |
| ++	      FIELD_PREP(MTK_PPE_TB_CFG_KEEPALIVE,
 | |
| ++			 MTK_PPE_KEEPALIVE_DISABLE) |
 | |
| ++	      FIELD_PREP(MTK_PPE_TB_CFG_HASH_MODE, 1) |
 | |
| ++	      FIELD_PREP(MTK_PPE_TB_CFG_SCAN_MODE,
 | |
| ++			 MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) |
 | |
| ++	      FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
 | |
| ++			 MTK_PPE_ENTRIES_SHIFT);
 | |
| ++	ppe_w32(ppe, MTK_PPE_TB_CFG, val);
 | |
| ++
 | |
| ++	ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK,
 | |
| ++		MTK_PPE_IP_PROTO_CHK_IPV4 | MTK_PPE_IP_PROTO_CHK_IPV6);
 | |
| ++
 | |
| ++	mtk_ppe_cache_enable(ppe, true);
 | |
| ++
 | |
| ++	val = MTK_PPE_FLOW_CFG_IP4_TCP_FRAG |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP4_UDP_FRAG |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP6_3T_ROUTE |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP6_5T_ROUTE |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP6_6RD |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP4_NAT |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP4_NAPT |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP4_DSLITE |
 | |
| ++	      MTK_PPE_FLOW_CFG_L2_BRIDGE |
 | |
| ++	      MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
 | |
| ++	ppe_w32(ppe, MTK_PPE_FLOW_CFG, val);
 | |
| ++
 | |
| ++	val = FIELD_PREP(MTK_PPE_UNBIND_AGE_MIN_PACKETS, 1000) |
 | |
| ++	      FIELD_PREP(MTK_PPE_UNBIND_AGE_DELTA, 3);
 | |
| ++	ppe_w32(ppe, MTK_PPE_UNBIND_AGE, val);
 | |
| ++
 | |
| ++	val = FIELD_PREP(MTK_PPE_BIND_AGE0_DELTA_UDP, 12) |
 | |
| ++	      FIELD_PREP(MTK_PPE_BIND_AGE0_DELTA_NON_L4, 1);
 | |
| ++	ppe_w32(ppe, MTK_PPE_BIND_AGE0, val);
 | |
| ++
 | |
| ++	val = FIELD_PREP(MTK_PPE_BIND_AGE1_DELTA_TCP_FIN, 1) |
 | |
| ++	      FIELD_PREP(MTK_PPE_BIND_AGE1_DELTA_TCP, 7);
 | |
| ++	ppe_w32(ppe, MTK_PPE_BIND_AGE1, val);
 | |
| ++
 | |
| ++	val = MTK_PPE_BIND_LIMIT0_QUARTER | MTK_PPE_BIND_LIMIT0_HALF;
 | |
| ++	ppe_w32(ppe, MTK_PPE_BIND_LIMIT0, val);
 | |
| ++
 | |
| ++	val = MTK_PPE_BIND_LIMIT1_FULL |
 | |
| ++	      FIELD_PREP(MTK_PPE_BIND_LIMIT1_NON_L4, 1);
 | |
| ++	ppe_w32(ppe, MTK_PPE_BIND_LIMIT1, val);
 | |
| ++
 | |
| ++	val = FIELD_PREP(MTK_PPE_BIND_RATE_BIND, 30) |
 | |
| ++	      FIELD_PREP(MTK_PPE_BIND_RATE_PREBIND, 1);
 | |
| ++	ppe_w32(ppe, MTK_PPE_BIND_RATE, val);
 | |
| ++
 | |
| ++	/* enable PPE */
 | |
| ++	val = MTK_PPE_GLO_CFG_EN |
 | |
| ++	      MTK_PPE_GLO_CFG_IP4_L4_CS_DROP |
 | |
| ++	      MTK_PPE_GLO_CFG_IP4_CS_DROP |
 | |
| ++	      MTK_PPE_GLO_CFG_FLOW_DROP_UPDATE;
 | |
| ++	ppe_w32(ppe, MTK_PPE_GLO_CFG, val);
 | |
| ++
 | |
| ++	ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_ppe_stop(struct mtk_ppe *ppe)
 | |
| ++{
 | |
| ++	u32 val;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	for (i = 0; i < MTK_PPE_ENTRIES; i++)
 | |
| ++		ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
 | |
| ++						   MTK_FOE_STATE_INVALID);
 | |
| ++
 | |
| ++	mtk_ppe_cache_enable(ppe, false);
 | |
| ++
 | |
| ++	/* disable offload engine */
 | |
| ++	ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN);
 | |
| ++	ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0);
 | |
| ++
 | |
| ++	/* disable aging */
 | |
| ++	val = MTK_PPE_TB_CFG_AGE_NON_L4 |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_UNBIND |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_TCP |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_UDP |
 | |
| ++	      MTK_PPE_TB_CFG_AGE_TCP_FIN;
 | |
| ++	ppe_clear(ppe, MTK_PPE_TB_CFG, val);
 | |
| ++
 | |
| ++	return mtk_ppe_wait_busy(ppe);
 | |
| ++}
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
 | |
| +@@ -0,0 +1,287 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0-only
 | |
| ++/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
 | |
| ++
 | |
| ++#ifndef __MTK_PPE_H
 | |
| ++#define __MTK_PPE_H
 | |
| ++
 | |
| ++#include <linux/kernel.h>
 | |
| ++#include <linux/bitfield.h>
 | |
| ++
 | |
| ++#define MTK_ETH_PPE_BASE		0xc00
 | |
| ++
 | |
| ++#define MTK_PPE_ENTRIES_SHIFT		3
 | |
| ++#define MTK_PPE_ENTRIES			(1024 << MTK_PPE_ENTRIES_SHIFT)
 | |
| ++#define MTK_PPE_HASH_MASK		(MTK_PPE_ENTRIES - 1)
 | |
| ++
 | |
| ++#define MTK_FOE_IB1_UNBIND_TIMESTAMP	GENMASK(7, 0)
 | |
| ++#define MTK_FOE_IB1_UNBIND_PACKETS	GENMASK(23, 8)
 | |
| ++#define MTK_FOE_IB1_UNBIND_PREBIND	BIT(24)
 | |
| ++
 | |
| ++#define MTK_FOE_IB1_BIND_TIMESTAMP	GENMASK(14, 0)
 | |
| ++#define MTK_FOE_IB1_BIND_KEEPALIVE	BIT(15)
 | |
| ++#define MTK_FOE_IB1_BIND_VLAN_LAYER	GENMASK(18, 16)
 | |
| ++#define MTK_FOE_IB1_BIND_PPPOE		BIT(19)
 | |
| ++#define MTK_FOE_IB1_BIND_VLAN_TAG	BIT(20)
 | |
| ++#define MTK_FOE_IB1_BIND_PKT_SAMPLE	BIT(21)
 | |
| ++#define MTK_FOE_IB1_BIND_CACHE		BIT(22)
 | |
| ++#define MTK_FOE_IB1_BIND_TUNNEL_DECAP	BIT(23)
 | |
| ++#define MTK_FOE_IB1_BIND_TTL		BIT(24)
 | |
| ++
 | |
| ++#define MTK_FOE_IB1_PACKET_TYPE		GENMASK(27, 25)
 | |
| ++#define MTK_FOE_IB1_STATE		GENMASK(29, 28)
 | |
| ++#define MTK_FOE_IB1_UDP			BIT(30)
 | |
| ++#define MTK_FOE_IB1_STATIC		BIT(31)
 | |
| ++
 | |
| ++enum {
 | |
| ++	MTK_PPE_PKT_TYPE_IPV4_HNAPT = 0,
 | |
| ++	MTK_PPE_PKT_TYPE_IPV4_ROUTE = 1,
 | |
| ++	MTK_PPE_PKT_TYPE_BRIDGE = 2,
 | |
| ++	MTK_PPE_PKT_TYPE_IPV4_DSLITE = 3,
 | |
| ++	MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T = 4,
 | |
| ++	MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T = 5,
 | |
| ++	MTK_PPE_PKT_TYPE_IPV6_6RD = 7,
 | |
| ++};
 | |
| ++
 | |
| ++#define MTK_FOE_IB2_QID			GENMASK(3, 0)
 | |
| ++#define MTK_FOE_IB2_PSE_QOS		BIT(4)
 | |
| ++#define MTK_FOE_IB2_DEST_PORT		GENMASK(7, 5)
 | |
| ++#define MTK_FOE_IB2_MULTICAST		BIT(8)
 | |
| ++
 | |
| ++#define MTK_FOE_IB2_WHNAT_QID2		GENMASK(13, 12)
 | |
| ++#define MTK_FOE_IB2_WHNAT_DEVIDX	BIT(16)
 | |
| ++#define MTK_FOE_IB2_WHNAT_NAT		BIT(17)
 | |
| ++
 | |
| ++#define MTK_FOE_IB2_PORT_MG		GENMASK(17, 12)
 | |
| ++
 | |
| ++#define MTK_FOE_IB2_PORT_AG		GENMASK(23, 18)
 | |
| ++
 | |
| ++#define MTK_FOE_IB2_DSCP		GENMASK(31, 24)
 | |
| ++
 | |
| ++#define MTK_FOE_VLAN2_WHNAT_BSS		GEMMASK(5, 0)
 | |
| ++#define MTK_FOE_VLAN2_WHNAT_WCID	GENMASK(13, 6)
 | |
| ++#define MTK_FOE_VLAN2_WHNAT_RING	GENMASK(15, 14)
 | |
| ++
 | |
| ++enum {
 | |
| ++	MTK_FOE_STATE_INVALID,
 | |
| ++	MTK_FOE_STATE_UNBIND,
 | |
| ++	MTK_FOE_STATE_BIND,
 | |
| ++	MTK_FOE_STATE_FIN
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_foe_mac_info {
 | |
| ++	u16 vlan1;
 | |
| ++	u16 etype;
 | |
| ++
 | |
| ++	u32 dest_mac_hi;
 | |
| ++
 | |
| ++	u16 vlan2;
 | |
| ++	u16 dest_mac_lo;
 | |
| ++
 | |
| ++	u32 src_mac_hi;
 | |
| ++
 | |
| ++	u16 pppoe_id;
 | |
| ++	u16 src_mac_lo;
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_foe_bridge {
 | |
| ++	u32 dest_mac_hi;
 | |
| ++
 | |
| ++	u16 src_mac_lo;
 | |
| ++	u16 dest_mac_lo;
 | |
| ++
 | |
| ++	u32 src_mac_hi;
 | |
| ++
 | |
| ++	u32 ib2;
 | |
| ++
 | |
| ++	u32 _rsv[5];
 | |
| ++
 | |
| ++	u32 udf_tsid;
 | |
| ++	struct mtk_foe_mac_info l2;
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_ipv4_tuple {
 | |
| ++	u32 src_ip;
 | |
| ++	u32 dest_ip;
 | |
| ++	union {
 | |
| ++		struct {
 | |
| ++			u16 dest_port;
 | |
| ++			u16 src_port;
 | |
| ++		};
 | |
| ++		struct {
 | |
| ++			u8 protocol;
 | |
| ++			u8 _pad[3]; /* fill with 0xa5a5a5 */
 | |
| ++		};
 | |
| ++		u32 ports;
 | |
| ++	};
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_foe_ipv4 {
 | |
| ++	struct mtk_ipv4_tuple orig;
 | |
| ++
 | |
| ++	u32 ib2;
 | |
| ++
 | |
| ++	struct mtk_ipv4_tuple new;
 | |
| ++
 | |
| ++	u16 timestamp;
 | |
| ++	u16 _rsv0[3];
 | |
| ++
 | |
| ++	u32 udf_tsid;
 | |
| ++
 | |
| ++	struct mtk_foe_mac_info l2;
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_foe_ipv4_dslite {
 | |
| ++	struct mtk_ipv4_tuple ip4;
 | |
| ++
 | |
| ++	u32 tunnel_src_ip[4];
 | |
| ++	u32 tunnel_dest_ip[4];
 | |
| ++
 | |
| ++	u8 flow_label[3];
 | |
| ++	u8 priority;
 | |
| ++
 | |
| ++	u32 udf_tsid;
 | |
| ++
 | |
| ++	u32 ib2;
 | |
| ++
 | |
| ++	struct mtk_foe_mac_info l2;
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_foe_ipv6 {
 | |
| ++	u32 src_ip[4];
 | |
| ++	u32 dest_ip[4];
 | |
| ++
 | |
| ++	union {
 | |
| ++		struct {
 | |
| ++			u8 protocol;
 | |
| ++			u8 _pad[3]; /* fill with 0xa5a5a5 */
 | |
| ++		}; /* 3-tuple */
 | |
| ++		struct {
 | |
| ++			u16 dest_port;
 | |
| ++			u16 src_port;
 | |
| ++		}; /* 5-tuple */
 | |
| ++		u32 ports;
 | |
| ++	};
 | |
| ++
 | |
| ++	u32 _rsv[3];
 | |
| ++
 | |
| ++	u32 udf;
 | |
| ++
 | |
| ++	u32 ib2;
 | |
| ++	struct mtk_foe_mac_info l2;
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_foe_ipv6_6rd {
 | |
| ++	u32 src_ip[4];
 | |
| ++	u32 dest_ip[4];
 | |
| ++	u16 dest_port;
 | |
| ++	u16 src_port;
 | |
| ++
 | |
| ++	u32 tunnel_src_ip;
 | |
| ++	u32 tunnel_dest_ip;
 | |
| ++
 | |
| ++	u16 hdr_csum;
 | |
| ++	u8 dscp;
 | |
| ++	u8 ttl;
 | |
| ++
 | |
| ++	u8 flag;
 | |
| ++	u8 pad;
 | |
| ++	u8 per_flow_6rd_id;
 | |
| ++	u8 pad2;
 | |
| ++
 | |
| ++	u32 ib2;
 | |
| ++	struct mtk_foe_mac_info l2;
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_foe_entry {
 | |
| ++	u32 ib1;
 | |
| ++
 | |
| ++	union {
 | |
| ++		struct mtk_foe_bridge bridge;
 | |
| ++		struct mtk_foe_ipv4 ipv4;
 | |
| ++		struct mtk_foe_ipv4_dslite dslite;
 | |
| ++		struct mtk_foe_ipv6 ipv6;
 | |
| ++		struct mtk_foe_ipv6_6rd ipv6_6rd;
 | |
| ++		u32 data[19];
 | |
| ++	};
 | |
| ++};
 | |
| ++
 | |
| ++enum {
 | |
| ++	MTK_PPE_CPU_REASON_TTL_EXCEEDED			= 0x02,
 | |
| ++	MTK_PPE_CPU_REASON_OPTION_HEADER		= 0x03,
 | |
| ++	MTK_PPE_CPU_REASON_NO_FLOW			= 0x07,
 | |
| ++	MTK_PPE_CPU_REASON_IPV4_FRAG			= 0x08,
 | |
| ++	MTK_PPE_CPU_REASON_IPV4_DSLITE_FRAG		= 0x09,
 | |
| ++	MTK_PPE_CPU_REASON_IPV4_DSLITE_NO_TCP_UDP	= 0x0a,
 | |
| ++	MTK_PPE_CPU_REASON_IPV6_6RD_NO_TCP_UDP		= 0x0b,
 | |
| ++	MTK_PPE_CPU_REASON_TCP_FIN_SYN_RST		= 0x0c,
 | |
| ++	MTK_PPE_CPU_REASON_UN_HIT			= 0x0d,
 | |
| ++	MTK_PPE_CPU_REASON_HIT_UNBIND			= 0x0e,
 | |
| ++	MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED	= 0x0f,
 | |
| ++	MTK_PPE_CPU_REASON_HIT_BIND_TCP_FIN		= 0x10,
 | |
| ++	MTK_PPE_CPU_REASON_HIT_TTL_1			= 0x11,
 | |
| ++	MTK_PPE_CPU_REASON_HIT_BIND_VLAN_VIOLATION	= 0x12,
 | |
| ++	MTK_PPE_CPU_REASON_KEEPALIVE_UC_OLD_HDR		= 0x13,
 | |
| ++	MTK_PPE_CPU_REASON_KEEPALIVE_MC_NEW_HDR		= 0x14,
 | |
| ++	MTK_PPE_CPU_REASON_KEEPALIVE_DUP_OLD_HDR	= 0x15,
 | |
| ++	MTK_PPE_CPU_REASON_HIT_BIND_FORCE_CPU		= 0x16,
 | |
| ++	MTK_PPE_CPU_REASON_TUNNEL_OPTION_HEADER		= 0x17,
 | |
| ++	MTK_PPE_CPU_REASON_MULTICAST_TO_CPU		= 0x18,
 | |
| ++	MTK_PPE_CPU_REASON_MULTICAST_TO_GMAC1_CPU	= 0x19,
 | |
| ++	MTK_PPE_CPU_REASON_HIT_PRE_BIND			= 0x1a,
 | |
| ++	MTK_PPE_CPU_REASON_PACKET_SAMPLING		= 0x1b,
 | |
| ++	MTK_PPE_CPU_REASON_EXCEED_MTU			= 0x1c,
 | |
| ++	MTK_PPE_CPU_REASON_PPE_BYPASS			= 0x1e,
 | |
| ++	MTK_PPE_CPU_REASON_INVALID			= 0x1f,
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_ppe {
 | |
| ++	struct device *dev;
 | |
| ++	void __iomem *base;
 | |
| ++	int version;
 | |
| ++
 | |
| ++	struct mtk_foe_entry *foe_table;
 | |
| ++	dma_addr_t foe_phys;
 | |
| ++
 | |
| ++	void *acct_table;
 | |
| ++};
 | |
| ++
 | |
| ++int mtk_ppe_init(struct mtk_ppe *ppe, struct device *dev, void __iomem *base,
 | |
| ++		 int version);
 | |
| ++int mtk_ppe_start(struct mtk_ppe *ppe);
 | |
| ++int mtk_ppe_stop(struct mtk_ppe *ppe);
 | |
| ++
 | |
| ++static inline void
 | |
| ++mtk_foe_entry_clear(struct mtk_ppe *ppe, u16 hash)
 | |
| ++{
 | |
| ++	ppe->foe_table[hash].ib1 = 0;
 | |
| ++	dma_wmb();
 | |
| ++}
 | |
| ++
 | |
| ++static inline int
 | |
| ++mtk_foe_entry_timestamp(struct mtk_ppe *ppe, u16 hash)
 | |
| ++{
 | |
| ++	u32 ib1 = READ_ONCE(ppe->foe_table[hash].ib1);
 | |
| ++
 | |
| ++	if (FIELD_GET(MTK_FOE_IB1_STATE, ib1) != MTK_FOE_STATE_BIND)
 | |
| ++		return -1;
 | |
| ++
 | |
| ++	return FIELD_GET(MTK_FOE_IB1_BIND_TIMESTAMP, ib1);
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto,
 | |
| ++			  u8 pse_port, u8 *src_mac, u8 *dest_mac);
 | |
| ++int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port);
 | |
| ++int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig,
 | |
| ++				 __be32 src_addr, __be16 src_port,
 | |
| ++				 __be32 dest_addr, __be16 dest_port);
 | |
| ++int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry,
 | |
| ++				 __be32 *src_addr, __be16 src_port,
 | |
| ++				 __be32 *dest_addr, __be16 dest_port);
 | |
| ++int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port);
 | |
| ++int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
 | |
| ++int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
 | |
| ++int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
 | |
| ++			 u16 timestamp);
 | |
| ++int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
 | |
| ++
 | |
| ++#endif
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
 | |
| +@@ -0,0 +1,217 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0-only
 | |
| ++/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
 | |
| ++
 | |
| ++#include <linux/kernel.h>
 | |
| ++#include <linux/debugfs.h>
 | |
| ++#include "mtk_eth_soc.h"
 | |
| ++
 | |
| ++struct mtk_flow_addr_info
 | |
| ++{
 | |
| ++	void *src, *dest;
 | |
| ++	u16 *src_port, *dest_port;
 | |
| ++	bool ipv6;
 | |
| ++};
 | |
| ++
 | |
| ++static const char *mtk_foe_entry_state_str(int state)
 | |
| ++{
 | |
| ++	static const char * const state_str[] = {
 | |
| ++		[MTK_FOE_STATE_INVALID] = "INV",
 | |
| ++		[MTK_FOE_STATE_UNBIND] = "UNB",
 | |
| ++		[MTK_FOE_STATE_BIND] = "BND",
 | |
| ++		[MTK_FOE_STATE_FIN] = "FIN",
 | |
| ++	};
 | |
| ++
 | |
| ++	if (state >= ARRAY_SIZE(state_str) || !state_str[state])
 | |
| ++		return "UNK";
 | |
| ++
 | |
| ++	return state_str[state];
 | |
| ++}
 | |
| ++
 | |
| ++static const char *mtk_foe_pkt_type_str(int type)
 | |
| ++{
 | |
| ++	static const char * const type_str[] = {
 | |
| ++		[MTK_PPE_PKT_TYPE_IPV4_HNAPT] = "IPv4 5T",
 | |
| ++		[MTK_PPE_PKT_TYPE_IPV4_ROUTE] = "IPv4 3T",
 | |
| ++		[MTK_PPE_PKT_TYPE_BRIDGE] = "L2",
 | |
| ++		[MTK_PPE_PKT_TYPE_IPV4_DSLITE] = "DS-LITE",
 | |
| ++		[MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T] = "IPv6 3T",
 | |
| ++		[MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T] = "IPv6 5T",
 | |
| ++		[MTK_PPE_PKT_TYPE_IPV6_6RD] = "6RD",
 | |
| ++	};
 | |
| ++
 | |
| ++	if (type >= ARRAY_SIZE(type_str) || !type_str[type])
 | |
| ++		return "UNKNOWN";
 | |
| ++
 | |
| ++	return type_str[type];
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++mtk_print_addr(struct seq_file *m, u32 *addr, bool ipv6)
 | |
| ++{
 | |
| ++	u32 n_addr[4];
 | |
| ++	int i;
 | |
| ++
 | |
| ++	if (!ipv6) {
 | |
| ++		seq_printf(m, "%pI4h", addr);
 | |
| ++		return;
 | |
| ++	}
 | |
| ++
 | |
| ++	for (i = 0; i < ARRAY_SIZE(n_addr); i++)
 | |
| ++		n_addr[i] = htonl(addr[i]);
 | |
| ++	seq_printf(m, "%pI6", n_addr);
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++mtk_print_addr_info(struct seq_file *m, struct mtk_flow_addr_info *ai)
 | |
| ++{
 | |
| ++	mtk_print_addr(m, ai->src, ai->ipv6);
 | |
| ++	if (ai->src_port)
 | |
| ++		seq_printf(m, ":%d", *ai->src_port);
 | |
| ++	seq_printf(m, "->");
 | |
| ++	mtk_print_addr(m, ai->dest, ai->ipv6);
 | |
| ++	if (ai->dest_port)
 | |
| ++		seq_printf(m, ":%d", *ai->dest_port);
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 | |
| ++{
 | |
| ++	struct mtk_ppe *ppe = m->private;
 | |
| ++	int i, count;
 | |
| ++
 | |
| ++	for (i = 0, count = 0; i < MTK_PPE_ENTRIES; i++) {
 | |
| ++		struct mtk_foe_entry *entry = &ppe->foe_table[i];
 | |
| ++		struct mtk_foe_mac_info *l2;
 | |
| ++		struct mtk_flow_addr_info ai = {};
 | |
| ++		unsigned char h_source[ETH_ALEN];
 | |
| ++		unsigned char h_dest[ETH_ALEN];
 | |
| ++		int type, state;
 | |
| ++		u32 ib2;
 | |
| ++
 | |
| ++
 | |
| ++		state = FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1);
 | |
| ++		if (!state)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		if (bind && state != MTK_FOE_STATE_BIND)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 | |
| ++		seq_printf(m, "%05x %s %7s", i,
 | |
| ++			   mtk_foe_entry_state_str(state),
 | |
| ++			   mtk_foe_pkt_type_str(type));
 | |
| ++
 | |
| ++		switch (type) {
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_DSLITE:
 | |
| ++			ai.src_port = &entry->ipv4.orig.src_port;
 | |
| ++			ai.dest_port = &entry->ipv4.orig.dest_port;
 | |
| ++			fallthrough;
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
 | |
| ++			ai.src = &entry->ipv4.orig.src_ip;
 | |
| ++			ai.dest = &entry->ipv4.orig.dest_ip;
 | |
| ++			break;
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV6_ROUTE_5T:
 | |
| ++			ai.src_port = &entry->ipv6.src_port;
 | |
| ++			ai.dest_port = &entry->ipv6.dest_port;
 | |
| ++			fallthrough;
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV6_ROUTE_3T:
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV6_6RD:
 | |
| ++			ai.src = &entry->ipv6.src_ip;
 | |
| ++			ai.dest = &entry->ipv6.dest_ip;
 | |
| ++			ai.ipv6 = true;
 | |
| ++			break;
 | |
| ++		}
 | |
| ++
 | |
| ++		seq_printf(m, " orig=");
 | |
| ++		mtk_print_addr_info(m, &ai);
 | |
| ++
 | |
| ++		switch (type) {
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_HNAPT:
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_DSLITE:
 | |
| ++			ai.src_port = &entry->ipv4.new.src_port;
 | |
| ++			ai.dest_port = &entry->ipv4.new.dest_port;
 | |
| ++			fallthrough;
 | |
| ++		case MTK_PPE_PKT_TYPE_IPV4_ROUTE:
 | |
| ++			ai.src = &entry->ipv4.new.src_ip;
 | |
| ++			ai.dest = &entry->ipv4.new.dest_ip;
 | |
| ++			seq_printf(m, " new=");
 | |
| ++			mtk_print_addr_info(m, &ai);
 | |
| ++			break;
 | |
| ++		}
 | |
| ++
 | |
| ++		if (type >= MTK_PPE_PKT_TYPE_IPV4_DSLITE) {
 | |
| ++			l2 = &entry->ipv6.l2;
 | |
| ++			ib2 = entry->ipv6.ib2;
 | |
| ++		} else {
 | |
| ++			l2 = &entry->ipv4.l2;
 | |
| ++			ib2 = entry->ipv4.ib2;
 | |
| ++		}
 | |
| ++
 | |
| ++		*((__be32 *)h_source) = htonl(l2->src_mac_hi);
 | |
| ++		*((__be16 *)&h_source[4]) = htons(l2->src_mac_lo);
 | |
| ++		*((__be32 *)h_dest) = htonl(l2->dest_mac_hi);
 | |
| ++		*((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
 | |
| ++
 | |
| ++		seq_printf(m, " eth=%pM->%pM etype=%04x"
 | |
| ++			      " vlan=%d,%d ib1=%08x ib2=%08x\n",
 | |
| ++			   h_source, h_dest, ntohs(l2->etype),
 | |
| ++			   l2->vlan1, l2->vlan2, entry->ib1, ib2);
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_ppe_debugfs_foe_show_all(struct seq_file *m, void *private)
 | |
| ++{
 | |
| ++	return mtk_ppe_debugfs_foe_show(m, private, false);
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_ppe_debugfs_foe_show_bind(struct seq_file *m, void *private)
 | |
| ++{
 | |
| ++	return mtk_ppe_debugfs_foe_show(m, private, true);
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_ppe_debugfs_foe_open_all(struct inode *inode, struct file *file)
 | |
| ++{
 | |
| ++	return single_open(file, mtk_ppe_debugfs_foe_show_all,
 | |
| ++			   inode->i_private);
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_ppe_debugfs_foe_open_bind(struct inode *inode, struct file *file)
 | |
| ++{
 | |
| ++	return single_open(file, mtk_ppe_debugfs_foe_show_bind,
 | |
| ++			   inode->i_private);
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
 | |
| ++{
 | |
| ++	static const struct file_operations fops_all = {
 | |
| ++		.open = mtk_ppe_debugfs_foe_open_all,
 | |
| ++		.read = seq_read,
 | |
| ++		.llseek = seq_lseek,
 | |
| ++		.release = single_release,
 | |
| ++	};
 | |
| ++
 | |
| ++	static const struct file_operations fops_bind = {
 | |
| ++		.open = mtk_ppe_debugfs_foe_open_bind,
 | |
| ++		.read = seq_read,
 | |
| ++		.llseek = seq_lseek,
 | |
| ++		.release = single_release,
 | |
| ++	};
 | |
| ++
 | |
| ++	struct dentry *root;
 | |
| ++
 | |
| ++	root = debugfs_create_dir("mtk_ppe", NULL);
 | |
| ++	if (!root)
 | |
| ++		return -ENOMEM;
 | |
| ++
 | |
| ++	debugfs_create_file("entries", S_IRUGO, root, ppe, &fops_all);
 | |
| ++	debugfs_create_file("bind", S_IRUGO, root, ppe, &fops_bind);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
 | |
| +@@ -0,0 +1,144 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0-only
 | |
| ++/* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
 | |
| ++
 | |
| ++#ifndef __MTK_PPE_REGS_H
 | |
| ++#define __MTK_PPE_REGS_H
 | |
| ++
 | |
| ++#define MTK_PPE_GLO_CFG				0x200
 | |
| ++#define MTK_PPE_GLO_CFG_EN			BIT(0)
 | |
| ++#define MTK_PPE_GLO_CFG_TSID_EN			BIT(1)
 | |
| ++#define MTK_PPE_GLO_CFG_IP4_L4_CS_DROP		BIT(2)
 | |
| ++#define MTK_PPE_GLO_CFG_IP4_CS_DROP		BIT(3)
 | |
| ++#define MTK_PPE_GLO_CFG_TTL0_DROP		BIT(4)
 | |
| ++#define MTK_PPE_GLO_CFG_PPE_BSWAP		BIT(5)
 | |
| ++#define MTK_PPE_GLO_CFG_PSE_HASH_OFS		BIT(6)
 | |
| ++#define MTK_PPE_GLO_CFG_MCAST_TB_EN		BIT(7)
 | |
| ++#define MTK_PPE_GLO_CFG_FLOW_DROP_KA		BIT(8)
 | |
| ++#define MTK_PPE_GLO_CFG_FLOW_DROP_UPDATE	BIT(9)
 | |
| ++#define MTK_PPE_GLO_CFG_UDP_LITE_EN		BIT(10)
 | |
| ++#define MTK_PPE_GLO_CFG_UDP_LEN_DROP		BIT(11)
 | |
| ++#define MTK_PPE_GLO_CFG_MCAST_ENTRIES		GNEMASK(13, 12)
 | |
| ++#define MTK_PPE_GLO_CFG_BUSY			BIT(31)
 | |
| ++
 | |
| ++#define MTK_PPE_FLOW_CFG			0x204
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG		BIT(6)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG		BIT(7)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE		BIT(8)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP6_5T_ROUTE		BIT(9)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP6_6RD		BIT(10)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_NAT		BIT(12)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_NAPT		BIT(13)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_DSLITE		BIT(14)
 | |
| ++#define MTK_PPE_FLOW_CFG_L2_BRIDGE		BIT(15)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP_PROTO_BLACKLIST	BIT(16)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_NAT_FRAG		BIT(17)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_HASH_FLOW_LABEL	BIT(18)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP4_HASH_GRE_KEY	BIT(19)
 | |
| ++#define MTK_PPE_FLOW_CFG_IP6_HASH_GRE_KEY	BIT(20)
 | |
| ++
 | |
| ++#define MTK_PPE_IP_PROTO_CHK			0x208
 | |
| ++#define MTK_PPE_IP_PROTO_CHK_IPV4		GENMASK(15, 0)
 | |
| ++#define MTK_PPE_IP_PROTO_CHK_IPV6		GENMASK(31, 16)
 | |
| ++
 | |
| ++#define MTK_PPE_TB_CFG				0x21c
 | |
| ++#define MTK_PPE_TB_CFG_ENTRY_NUM		GENMASK(2, 0)
 | |
| ++#define MTK_PPE_TB_CFG_ENTRY_80B		BIT(3)
 | |
| ++#define MTK_PPE_TB_CFG_SEARCH_MISS		GENMASK(5, 4)
 | |
| ++#define MTK_PPE_TB_CFG_AGE_PREBIND		BIT(6)
 | |
| ++#define MTK_PPE_TB_CFG_AGE_NON_L4		BIT(7)
 | |
| ++#define MTK_PPE_TB_CFG_AGE_UNBIND		BIT(8)
 | |
| ++#define MTK_PPE_TB_CFG_AGE_TCP			BIT(9)
 | |
| ++#define MTK_PPE_TB_CFG_AGE_UDP			BIT(10)
 | |
| ++#define MTK_PPE_TB_CFG_AGE_TCP_FIN		BIT(11)
 | |
| ++#define MTK_PPE_TB_CFG_KEEPALIVE		GENMASK(13, 12)
 | |
| ++#define MTK_PPE_TB_CFG_HASH_MODE		GENMASK(15, 14)
 | |
| ++#define MTK_PPE_TB_CFG_SCAN_MODE		GENMASK(17, 16)
 | |
| ++#define MTK_PPE_TB_CFG_HASH_DEBUG		GENMASK(19, 18)
 | |
| ++
 | |
| ++enum {
 | |
| ++	MTK_PPE_SCAN_MODE_DISABLED,
 | |
| ++	MTK_PPE_SCAN_MODE_CHECK_AGE,
 | |
| ++	MTK_PPE_SCAN_MODE_KEEPALIVE_AGE,
 | |
| ++};
 | |
| ++
 | |
| ++enum {
 | |
| ++	MTK_PPE_KEEPALIVE_DISABLE,
 | |
| ++	MTK_PPE_KEEPALIVE_UNICAST_CPU,
 | |
| ++	MTK_PPE_KEEPALIVE_DUP_CPU = 3,
 | |
| ++};
 | |
| ++
 | |
| ++enum {
 | |
| ++	MTK_PPE_SEARCH_MISS_ACTION_DROP,
 | |
| ++	MTK_PPE_SEARCH_MISS_ACTION_FORWARD = 2,
 | |
| ++	MTK_PPE_SEARCH_MISS_ACTION_FORWARD_BUILD = 3,
 | |
| ++};
 | |
| ++
 | |
| ++#define MTK_PPE_TB_BASE				0x220
 | |
| ++
 | |
| ++#define MTK_PPE_TB_USED				0x224
 | |
| ++#define MTK_PPE_TB_USED_NUM			GENMASK(13, 0)
 | |
| ++
 | |
| ++#define MTK_PPE_BIND_RATE			0x228
 | |
| ++#define MTK_PPE_BIND_RATE_BIND			GENMASK(15, 0)
 | |
| ++#define MTK_PPE_BIND_RATE_PREBIND		GENMASK(31, 16)
 | |
| ++
 | |
| ++#define MTK_PPE_BIND_LIMIT0			0x22c
 | |
| ++#define MTK_PPE_BIND_LIMIT0_QUARTER		GENMASK(13, 0)
 | |
| ++#define MTK_PPE_BIND_LIMIT0_HALF		GENMASK(29, 16)
 | |
| ++
 | |
| ++#define MTK_PPE_BIND_LIMIT1			0x230
 | |
| ++#define MTK_PPE_BIND_LIMIT1_FULL		GENMASK(13, 0)
 | |
| ++#define MTK_PPE_BIND_LIMIT1_NON_L4		GENMASK(23, 16)
 | |
| ++
 | |
| ++#define MTK_PPE_KEEPALIVE			0x234
 | |
| ++#define MTK_PPE_KEEPALIVE_TIME			GENMASK(15, 0)
 | |
| ++#define MTK_PPE_KEEPALIVE_TIME_TCP		GENMASK(23, 16)
 | |
| ++#define MTK_PPE_KEEPALIVE_TIME_UDP		GENMASK(31, 24)
 | |
| ++
 | |
| ++#define MTK_PPE_UNBIND_AGE			0x238
 | |
| ++#define MTK_PPE_UNBIND_AGE_MIN_PACKETS		GENMASK(31, 16)
 | |
| ++#define MTK_PPE_UNBIND_AGE_DELTA		GENMASK(7, 0)
 | |
| ++
 | |
| ++#define MTK_PPE_BIND_AGE0			0x23c
 | |
| ++#define MTK_PPE_BIND_AGE0_DELTA_NON_L4		GENMASK(30, 16)
 | |
| ++#define MTK_PPE_BIND_AGE0_DELTA_UDP		GENMASK(14, 0)
 | |
| ++
 | |
| ++#define MTK_PPE_BIND_AGE1			0x240
 | |
| ++#define MTK_PPE_BIND_AGE1_DELTA_TCP_FIN		GENMASK(30, 16)
 | |
| ++#define MTK_PPE_BIND_AGE1_DELTA_TCP		GENMASK(14, 0)
 | |
| ++
 | |
| ++#define MTK_PPE_HASH_SEED			0x244
 | |
| ++
 | |
| ++#define MTK_PPE_DEFAULT_CPU_PORT		0x248
 | |
| ++#define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n)	(GENMASK(2, 0) << ((_n) * 4))
 | |
| ++
 | |
| ++#define MTK_PPE_MTU_DROP			0x308
 | |
| ++
 | |
| ++#define MTK_PPE_VLAN_MTU0			0x30c
 | |
| ++#define MTK_PPE_VLAN_MTU0_NONE			GENMASK(13, 0)
 | |
| ++#define MTK_PPE_VLAN_MTU0_1TAG			GENMASK(29, 16)
 | |
| ++
 | |
| ++#define MTK_PPE_VLAN_MTU1			0x310
 | |
| ++#define MTK_PPE_VLAN_MTU1_2TAG			GENMASK(13, 0)
 | |
| ++#define MTK_PPE_VLAN_MTU1_3TAG			GENMASK(29, 16)
 | |
| ++
 | |
| ++#define MTK_PPE_VPM_TPID			0x318
 | |
| ++
 | |
| ++#define MTK_PPE_CACHE_CTL			0x320
 | |
| ++#define MTK_PPE_CACHE_CTL_EN			BIT(0)
 | |
| ++#define MTK_PPE_CACHE_CTL_LOCK_CLR		BIT(4)
 | |
| ++#define MTK_PPE_CACHE_CTL_REQ			BIT(8)
 | |
| ++#define MTK_PPE_CACHE_CTL_CLEAR			BIT(9)
 | |
| ++#define MTK_PPE_CACHE_CTL_CMD			GENMASK(13, 12)
 | |
| ++
 | |
| ++#define MTK_PPE_MIB_CFG				0x334
 | |
| ++#define MTK_PPE_MIB_CFG_EN			BIT(0)
 | |
| ++#define MTK_PPE_MIB_CFG_RD_CLR			BIT(1)
 | |
| ++
 | |
| ++#define MTK_PPE_MIB_TB_BASE			0x338
 | |
| ++
 | |
| ++#define MTK_PPE_MIB_CACHE_CTL			0x350
 | |
| ++#define MTK_PPE_MIB_CACHE_CTL_EN		BIT(0)
 | |
| ++#define MTK_PPE_MIB_CACHE_CTL_FLUSH		BIT(2)
 | |
| ++
 | |
| ++#endif
 | |
| diff --git a/target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch b/target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch
 | |
| new file mode 100644
 | |
| index 0000000000..2f1ae6cde6
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/770-16-net-ethernet-mtk_eth_soc-add-flow-offloading-support.patch
 | |
| @@ -0,0 +1,574 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Date: Thu, 10 Dec 2020 12:19:18 +0100
 | |
| +Subject: [PATCH] net: ethernet: mtk_eth_soc: add flow offloading support
 | |
| +
 | |
| +This adds support for offloading IPv4 routed flows, including SNAT/DNAT,
 | |
| +one VLAN, and DSA.
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 | |
| +---
 | |
| + create mode 100644 drivers/net/ethernet/mediatek/mtk_ppe_offload.c
 | |
| +
 | |
| +--- a/drivers/net/ethernet/mediatek/Makefile
 | |
| ++++ b/drivers/net/ethernet/mediatek/Makefile
 | |
| +@@ -4,5 +4,5 @@
 | |
| + #
 | |
| + 
 | |
| + obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
 | |
| +-mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o
 | |
| ++mtk_eth-y := mtk_eth_soc.o mtk_sgmii.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
 | |
| + obj-$(CONFIG_NET_MEDIATEK_STAR_EMAC) += mtk_star_emac.o
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 | |
| +@@ -2896,6 +2896,7 @@ static const struct net_device_ops mtk_n
 | |
| + #ifdef CONFIG_NET_POLL_CONTROLLER
 | |
| + 	.ndo_poll_controller	= mtk_poll_controller,
 | |
| + #endif
 | |
| ++	.ndo_setup_tc		= mtk_eth_setup_tc,
 | |
| + };
 | |
| + 
 | |
| + static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 | |
| +@@ -3161,6 +3162,10 @@ static int mtk_probe(struct platform_dev
 | |
| + 				   eth->base + MTK_ETH_PPE_BASE, 2);
 | |
| + 		if (err)
 | |
| + 			goto err_free_dev;
 | |
| ++
 | |
| ++		err = mtk_eth_offload_init(eth);
 | |
| ++		if (err)
 | |
| ++			goto err_free_dev;
 | |
| + 	}
 | |
| + 
 | |
| + 	for (i = 0; i < MTK_MAX_DEVS; i++) {
 | |
| +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 | |
| +@@ -16,6 +16,7 @@
 | |
| + #include <linux/refcount.h>
 | |
| + #include <linux/phylink.h>
 | |
| + #include <linux/dim.h>
 | |
| ++#include <linux/rhashtable.h>
 | |
| + #include "mtk_ppe.h"
 | |
| + 
 | |
| + #define MTK_QDMA_PAGE_SIZE	2048
 | |
| +@@ -41,7 +42,8 @@
 | |
| + 				 NETIF_F_HW_VLAN_CTAG_RX | \
 | |
| + 				 NETIF_F_SG | NETIF_F_TSO | \
 | |
| + 				 NETIF_F_TSO6 | \
 | |
| +-				 NETIF_F_IPV6_CSUM)
 | |
| ++				 NETIF_F_IPV6_CSUM |\
 | |
| ++				 NETIF_F_HW_TC)
 | |
| + #define MTK_HW_FEATURES_MT7628	(NETIF_F_SG | NETIF_F_RXCSUM)
 | |
| + #define NEXT_DESP_IDX(X, Y)	(((X) + 1) & ((Y) - 1))
 | |
| + 
 | |
| +@@ -929,6 +931,7 @@ struct mtk_eth {
 | |
| + 	int				ip_align;
 | |
| + 
 | |
| + 	struct mtk_ppe			ppe;
 | |
| ++	struct rhashtable		flow_table;
 | |
| + };
 | |
| + 
 | |
| + /* struct mtk_mac -	the structure that holds the info about the MACs of the
 | |
| +@@ -973,4 +976,9 @@ int mtk_gmac_sgmii_path_setup(struct mtk
 | |
| + int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
 | |
| + int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
 | |
| + 
 | |
| ++int mtk_eth_offload_init(struct mtk_eth *eth);
 | |
| ++int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 | |
| ++		     void *type_data);
 | |
| ++
 | |
| ++
 | |
| + #endif /* MTK_ETH_H */
 | |
| +--- /dev/null
 | |
| ++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
 | |
| +@@ -0,0 +1,491 @@
 | |
| ++// SPDX-License-Identifier: GPL-2.0-only
 | |
| ++/*
 | |
| ++ *  Copyright (C) 2020 Felix Fietkau <nbd@nbd.name>
 | |
| ++ */
 | |
| ++
 | |
| ++#include <linux/if_ether.h>
 | |
| ++#include <linux/rhashtable.h>
 | |
| ++#include <linux/if_ether.h>
 | |
| ++#include <linux/ip.h>
 | |
| ++#include <net/flow_offload.h>
 | |
| ++#include <net/pkt_cls.h>
 | |
| ++#include <net/dsa.h>
 | |
| ++#include "mtk_eth_soc.h"
 | |
| ++
 | |
| ++struct mtk_flow_data {
 | |
| ++	struct ethhdr eth;
 | |
| ++
 | |
| ++	union {
 | |
| ++		struct {
 | |
| ++			__be32 src_addr;
 | |
| ++			__be32 dst_addr;
 | |
| ++		} v4;
 | |
| ++	};
 | |
| ++
 | |
| ++	__be16 src_port;
 | |
| ++	__be16 dst_port;
 | |
| ++
 | |
| ++	struct {
 | |
| ++		u16 id;
 | |
| ++		__be16 proto;
 | |
| ++		u8 num;
 | |
| ++	} vlan;
 | |
| ++	struct {
 | |
| ++		u16 sid;
 | |
| ++		u8 num;
 | |
| ++	} pppoe;
 | |
| ++};
 | |
| ++
 | |
| ++struct mtk_flow_entry {
 | |
| ++	struct rhash_head node;
 | |
| ++	unsigned long cookie;
 | |
| ++	u16 hash;
 | |
| ++};
 | |
| ++
 | |
| ++static const struct rhashtable_params mtk_flow_ht_params = {
 | |
| ++	.head_offset = offsetof(struct mtk_flow_entry, node),
 | |
| ++	.head_offset = offsetof(struct mtk_flow_entry, cookie),
 | |
| ++	.key_len = sizeof(unsigned long),
 | |
| ++	.automatic_shrinking = true,
 | |
| ++};
 | |
| ++
 | |
| ++static u32
 | |
| ++mtk_eth_timestamp(struct mtk_eth *eth)
 | |
| ++{
 | |
| ++	return mtk_r32(eth, 0x0010) & MTK_FOE_IB1_BIND_TIMESTAMP;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data,
 | |
| ++		       bool egress)
 | |
| ++{
 | |
| ++	return mtk_foe_entry_set_ipv4_tuple(foe, egress,
 | |
| ++					    data->v4.src_addr, data->src_port,
 | |
| ++					    data->v4.dst_addr, data->dst_port);
 | |
| ++}
 | |
| ++
 | |
| ++static void
 | |
| ++mtk_flow_offload_mangle_eth(const struct flow_action_entry *act, void *eth)
 | |
| ++{
 | |
| ++	void *dest = eth + act->mangle.offset;
 | |
| ++	const void *src = &act->mangle.val;
 | |
| ++
 | |
| ++	if (act->mangle.offset > 8)
 | |
| ++		return;
 | |
| ++
 | |
| ++	if (act->mangle.mask == 0xffff) {
 | |
| ++		src += 2;
 | |
| ++		dest += 2;
 | |
| ++	}
 | |
| ++
 | |
| ++	memcpy(dest, src, act->mangle.mask ? 2 : 4);
 | |
| ++}
 | |
| ++
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_mangle_ports(const struct flow_action_entry *act,
 | |
| ++		      struct mtk_flow_data *data)
 | |
| ++{
 | |
| ++	u32 val = ntohl(act->mangle.val);
 | |
| ++
 | |
| ++	switch (act->mangle.offset) {
 | |
| ++	case 0:
 | |
| ++		if (act->mangle.mask == ~htonl(0xffff))
 | |
| ++			data->dst_port = cpu_to_be16(val);
 | |
| ++		else
 | |
| ++			data->src_port = cpu_to_be16(val >> 16);
 | |
| ++		break;
 | |
| ++	case 2:
 | |
| ++		data->dst_port = cpu_to_be16(val);
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return -EINVAL;
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_mangle_ipv4(const struct flow_action_entry *act,
 | |
| ++		     struct mtk_flow_data *data)
 | |
| ++{
 | |
| ++	__be32 *dest;
 | |
| ++
 | |
| ++	switch (act->mangle.offset) {
 | |
| ++	case offsetof(struct iphdr, saddr):
 | |
| ++		dest = &data->v4.src_addr;
 | |
| ++		break;
 | |
| ++	case offsetof(struct iphdr, daddr):
 | |
| ++		dest = &data->v4.dst_addr;
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return -EINVAL;
 | |
| ++	}
 | |
| ++
 | |
| ++	memcpy(dest, &act->mangle.val, sizeof(u32));
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_get_dsa_port(struct net_device **dev)
 | |
| ++{
 | |
| ++#if IS_ENABLED(CONFIG_NET_DSA)
 | |
| ++	struct dsa_port *dp;
 | |
| ++
 | |
| ++	dp = dsa_port_from_netdev(*dev);
 | |
| ++	if (IS_ERR(dp))
 | |
| ++		return -ENODEV;
 | |
| ++
 | |
| ++	if (!dp->cpu_dp)
 | |
| ++		return -ENODEV;
 | |
| ++
 | |
| ++	if (!dp->cpu_dp->tag_ops)
 | |
| ++		return -ENODEV;
 | |
| ++
 | |
| ++	if (dp->cpu_dp->tag_ops->proto != DSA_TAG_PROTO_MTK)
 | |
| ++		return -ENODEV;
 | |
| ++
 | |
| ++	*dev = dp->cpu_dp->master;
 | |
| ++
 | |
| ++	return dp->index;
 | |
| ++#else
 | |
| ++	return -ENODEV;
 | |
| ++#endif
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
 | |
| ++			   struct net_device *dev)
 | |
| ++{
 | |
| ++	int pse_port, dsa_port;
 | |
| ++
 | |
| ++	dsa_port = mtk_flow_get_dsa_port(&dev);
 | |
| ++	if (dsa_port >= 0)
 | |
| ++		mtk_foe_entry_set_dsa(foe, dsa_port);
 | |
| ++
 | |
| ++	if (dev == eth->netdev[0])
 | |
| ++		pse_port = 1;
 | |
| ++	else if (dev == eth->netdev[1])
 | |
| ++		pse_port = 2;
 | |
| ++	else
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	mtk_foe_entry_set_pse_port(foe, pse_port);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 | |
| ++{
 | |
| ++	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
 | |
| ++	struct flow_action_entry *act;
 | |
| ++	struct mtk_flow_data data = {};
 | |
| ++	struct mtk_foe_entry foe;
 | |
| ++	struct net_device *odev = NULL;
 | |
| ++	struct mtk_flow_entry *entry;
 | |
| ++	int offload_type = 0;
 | |
| ++	u16 addr_type = 0;
 | |
| ++	u32 timestamp;
 | |
| ++	u8 l4proto = 0;
 | |
| ++	int err = 0;
 | |
| ++	int hash;
 | |
| ++	int i;
 | |
| ++
 | |
| ++	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_META)) {
 | |
| ++		struct flow_match_meta match;
 | |
| ++
 | |
| ++		flow_rule_match_meta(rule, &match);
 | |
| ++	} else {
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
 | |
| ++		struct flow_match_control match;
 | |
| ++
 | |
| ++		flow_rule_match_control(rule, &match);
 | |
| ++		addr_type = match.key->addr_type;
 | |
| ++	} else {
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
 | |
| ++		struct flow_match_basic match;
 | |
| ++
 | |
| ++		flow_rule_match_basic(rule, &match);
 | |
| ++		l4proto = match.key->ip_proto;
 | |
| ++	} else {
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| ++
 | |
| ++	flow_action_for_each(i, act, &rule->action) {
 | |
| ++		switch (act->id) {
 | |
| ++		case FLOW_ACTION_MANGLE:
 | |
| ++			if (act->mangle.htype == FLOW_ACT_MANGLE_HDR_TYPE_ETH)
 | |
| ++				mtk_flow_offload_mangle_eth(act, &data.eth);
 | |
| ++			break;
 | |
| ++		case FLOW_ACTION_REDIRECT:
 | |
| ++			odev = act->dev;
 | |
| ++			break;
 | |
| ++		case FLOW_ACTION_CSUM:
 | |
| ++			break;
 | |
| ++		case FLOW_ACTION_VLAN_PUSH:
 | |
| ++			if (data.vlan.num == 1 ||
 | |
| ++			    act->vlan.proto != htons(ETH_P_8021Q))
 | |
| ++				return -EOPNOTSUPP;
 | |
| ++
 | |
| ++			data.vlan.id = act->vlan.vid;
 | |
| ++			data.vlan.proto = act->vlan.proto;
 | |
| ++			data.vlan.num++;
 | |
| ++			break;
 | |
| ++		case FLOW_ACTION_PPPOE_PUSH:
 | |
| ++			if (data.pppoe.num == 1)
 | |
| ++				return -EOPNOTSUPP;
 | |
| ++
 | |
| ++			data.pppoe.sid = act->pppoe.sid;
 | |
| ++			data.pppoe.num++;
 | |
| ++			break;
 | |
| ++		default:
 | |
| ++			return -EOPNOTSUPP;
 | |
| ++		}
 | |
| ++	}
 | |
| ++
 | |
| ++	switch (addr_type) {
 | |
| ++	case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
 | |
| ++		offload_type = MTK_PPE_PKT_TYPE_IPV4_HNAPT;
 | |
| ++		break;
 | |
| ++	default:
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (!is_valid_ether_addr(data.eth.h_source) ||
 | |
| ++	    !is_valid_ether_addr(data.eth.h_dest))
 | |
| ++		return -EINVAL;
 | |
| ++
 | |
| ++	err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0,
 | |
| ++				    data.eth.h_source,
 | |
| ++				    data.eth.h_dest);
 | |
| ++	if (err)
 | |
| ++		return err;
 | |
| ++
 | |
| ++	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
 | |
| ++		struct flow_match_ports ports;
 | |
| ++
 | |
| ++		flow_rule_match_ports(rule, &ports);
 | |
| ++		data.src_port = ports.key->src;
 | |
| ++		data.dst_port = ports.key->dst;
 | |
| ++	} else {
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
 | |
| ++		struct flow_match_ipv4_addrs addrs;
 | |
| ++
 | |
| ++		flow_rule_match_ipv4_addrs(rule, &addrs);
 | |
| ++
 | |
| ++		data.v4.src_addr = addrs.key->src;
 | |
| ++		data.v4.dst_addr = addrs.key->dst;
 | |
| ++
 | |
| ++		mtk_flow_set_ipv4_addr(&foe, &data, false);
 | |
| ++	}
 | |
| ++
 | |
| ++	flow_action_for_each(i, act, &rule->action) {
 | |
| ++		if (act->id != FLOW_ACTION_MANGLE)
 | |
| ++			continue;
 | |
| ++
 | |
| ++		switch (act->mangle.htype) {
 | |
| ++		case FLOW_ACT_MANGLE_HDR_TYPE_TCP:
 | |
| ++		case FLOW_ACT_MANGLE_HDR_TYPE_UDP:
 | |
| ++			err = mtk_flow_mangle_ports(act, &data);
 | |
| ++			break;
 | |
| ++		case FLOW_ACT_MANGLE_HDR_TYPE_IP4:
 | |
| ++			err = mtk_flow_mangle_ipv4(act, &data);
 | |
| ++			break;
 | |
| ++		case FLOW_ACT_MANGLE_HDR_TYPE_ETH:
 | |
| ++			/* handled earlier */
 | |
| ++			break;
 | |
| ++		default:
 | |
| ++			return -EOPNOTSUPP;
 | |
| ++		}
 | |
| ++
 | |
| ++		if (err)
 | |
| ++			return err;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
 | |
| ++		err = mtk_flow_set_ipv4_addr(&foe, &data, true);
 | |
| ++		if (err)
 | |
| ++			return err;
 | |
| ++	}
 | |
| ++
 | |
| ++	if (data.vlan.num == 1) {
 | |
| ++		if (data.vlan.proto != htons(ETH_P_8021Q))
 | |
| ++			return -EOPNOTSUPP;
 | |
| ++
 | |
| ++		mtk_foe_entry_set_vlan(&foe, data.vlan.id);
 | |
| ++	}
 | |
| ++	if (data.pppoe.num == 1)
 | |
| ++		mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid);
 | |
| ++
 | |
| ++	err = mtk_flow_set_output_device(eth, &foe, odev);
 | |
| ++	if (err)
 | |
| ++		return err;
 | |
| ++
 | |
| ++	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 | |
| ++	if (!entry)
 | |
| ++		return -ENOMEM;
 | |
| ++
 | |
| ++	entry->cookie = f->cookie;
 | |
| ++	timestamp = mtk_eth_timestamp(eth);
 | |
| ++	hash = mtk_foe_entry_commit(ð->ppe, &foe, timestamp);
 | |
| ++	if (hash < 0) {
 | |
| ++		err = hash;
 | |
| ++		goto free;
 | |
| ++	}
 | |
| ++
 | |
| ++	entry->hash = hash;
 | |
| ++	err = rhashtable_insert_fast(ð->flow_table, &entry->node,
 | |
| ++				     mtk_flow_ht_params);
 | |
| ++	if (err < 0)
 | |
| ++		goto clear_flow;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++clear_flow:
 | |
| ++	mtk_foe_entry_clear(ð->ppe, hash);
 | |
| ++free:
 | |
| ++	kfree(entry);
 | |
| ++	return err;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_offload_destroy(struct mtk_eth *eth, struct flow_cls_offload *f)
 | |
| ++{
 | |
| ++	struct mtk_flow_entry *entry;
 | |
| ++
 | |
| ++	entry = rhashtable_lookup(ð->flow_table, &f->cookie,
 | |
| ++				  mtk_flow_ht_params);
 | |
| ++	if (!entry)
 | |
| ++		return -ENOENT;
 | |
| ++
 | |
| ++	mtk_foe_entry_clear(ð->ppe, entry->hash);
 | |
| ++	rhashtable_remove_fast(ð->flow_table, &entry->node,
 | |
| ++			       mtk_flow_ht_params);
 | |
| ++	kfree(entry);
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
 | |
| ++{
 | |
| ++	struct mtk_flow_entry *entry;
 | |
| ++	int timestamp;
 | |
| ++	u32 idle;
 | |
| ++
 | |
| ++	entry = rhashtable_lookup(ð->flow_table, &f->cookie,
 | |
| ++				  mtk_flow_ht_params);
 | |
| ++	if (!entry)
 | |
| ++		return -ENOENT;
 | |
| ++
 | |
| ++	timestamp = mtk_foe_entry_timestamp(ð->ppe, entry->hash);
 | |
| ++	if (timestamp < 0)
 | |
| ++		return -ETIMEDOUT;
 | |
| ++
 | |
| ++	idle = mtk_eth_timestamp(eth) - timestamp;
 | |
| ++	f->stats.lastused = jiffies - idle * HZ;
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_eth_setup_tc_block_cb(enum tc_setup_type type, void *type_data, void *cb_priv)
 | |
| ++{
 | |
| ++	struct flow_cls_offload *cls = type_data;
 | |
| ++	struct net_device *dev = cb_priv;
 | |
| ++	struct mtk_mac *mac = netdev_priv(dev);
 | |
| ++	struct mtk_eth *eth = mac->hw;
 | |
| ++
 | |
| ++	if (!tc_can_offload(dev))
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	if (type != TC_SETUP_CLSFLOWER)
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	switch (cls->command) {
 | |
| ++	case FLOW_CLS_REPLACE:
 | |
| ++		return mtk_flow_offload_replace(eth, cls);
 | |
| ++	case FLOW_CLS_DESTROY:
 | |
| ++		return mtk_flow_offload_destroy(eth, cls);
 | |
| ++	case FLOW_CLS_STATS:
 | |
| ++		return mtk_flow_offload_stats(eth, cls);
 | |
| ++	default:
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| ++
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++static int
 | |
| ++mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
 | |
| ++{
 | |
| ++	struct mtk_mac *mac = netdev_priv(dev);
 | |
| ++	struct mtk_eth *eth = mac->hw;
 | |
| ++	static LIST_HEAD(block_cb_list);
 | |
| ++	struct flow_block_cb *block_cb;
 | |
| ++	flow_setup_cb_t *cb;
 | |
| ++
 | |
| ++	if (!eth->ppe.foe_table)
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++
 | |
| ++	cb = mtk_eth_setup_tc_block_cb;
 | |
| ++	f->driver_block_list = &block_cb_list;
 | |
| ++
 | |
| ++	switch (f->command) {
 | |
| ++	case FLOW_BLOCK_BIND:
 | |
| ++		block_cb = flow_block_cb_lookup(f->block, cb, dev);
 | |
| ++		if (block_cb) {
 | |
| ++			flow_block_cb_incref(block_cb);
 | |
| ++			return 0;
 | |
| ++		}
 | |
| ++		block_cb = flow_block_cb_alloc(cb, dev, dev, NULL);
 | |
| ++		if (IS_ERR(block_cb))
 | |
| ++			return PTR_ERR(block_cb);
 | |
| ++
 | |
| ++		flow_block_cb_add(block_cb, f);
 | |
| ++		list_add_tail(&block_cb->driver_list, &block_cb_list);
 | |
| ++		return 0;
 | |
| ++	case FLOW_BLOCK_UNBIND:
 | |
| ++		block_cb = flow_block_cb_lookup(f->block, cb, dev);
 | |
| ++		if (!block_cb)
 | |
| ++			return -ENOENT;
 | |
| ++
 | |
| ++		if (flow_block_cb_decref(block_cb)) {
 | |
| ++			flow_block_cb_remove(block_cb, f);
 | |
| ++			list_del(&block_cb->driver_list);
 | |
| ++		}
 | |
| ++		return 0;
 | |
| ++	default:
 | |
| ++		return -EOPNOTSUPP;
 | |
| ++	}
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 | |
| ++		     void *type_data)
 | |
| ++{
 | |
| ++	if (type == TC_SETUP_FT)
 | |
| ++		return mtk_eth_setup_tc_block(dev, type_data);
 | |
| ++
 | |
| ++	return -EOPNOTSUPP;
 | |
| ++}
 | |
| ++
 | |
| ++int mtk_eth_offload_init(struct mtk_eth *eth)
 | |
| ++{
 | |
| ++	if (!eth->ppe.foe_table)
 | |
| ++		return 0;
 | |
| ++
 | |
| ++	return rhashtable_init(ð->flow_table, &mtk_flow_ht_params);
 | |
| ++}
 | |
| diff --git a/target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch b/target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch
 | |
| new file mode 100644
 | |
| index 0000000000..cb02c71829
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/800-bcma-get-SoC-device-struct-copy-its-DMA-params-to-th.patch
 | |
| @@ -0,0 +1,70 @@
 | |
| +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | |
| +Subject: [PATCH] bcma: get SoC device struct & copy its DMA params to the
 | |
| + subdevices
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +For bus devices to be fully usable it's required to set their DMA
 | |
| +parameters.
 | |
| +
 | |
| +For years it has been missing and remained unnoticed because of
 | |
| +mips_dma_alloc_coherent() silently handling the empty coherent_dma_mask.
 | |
| +Kernel 4.19 came with a lot of DMA changes and caused a regression on
 | |
| +the bcm47xx. Starting with the commit f8c55dc6e828 ("MIPS: use generic
 | |
| +dma noncoherent ops for simple noncoherent platforms") DMA coherent
 | |
| +allocations just fail. Example:
 | |
| +[    1.114914] bgmac_bcma bcma0:2: Allocation of TX ring 0x200 failed
 | |
| +[    1.121215] bgmac_bcma bcma0:2: Unable to alloc memory for DMA
 | |
| +[    1.127626] bgmac_bcma: probe of bcma0:2 failed with error -12
 | |
| +[    1.133838] bgmac_bcma: Broadcom 47xx GBit MAC driver loaded
 | |
| +
 | |
| +This change fixes above regression in addition to the MIPS bcm47xx
 | |
| +commit 321c46b91550 ("MIPS: BCM47XX: Setup struct device for the SoC").
 | |
| +
 | |
| +It also fixes another *old* GPIO regression caused by a parent pointing
 | |
| +to the NULL:
 | |
| +[    0.157054] missing gpiochip .dev parent pointer
 | |
| +[    0.157287] bcma: bus0: Error registering GPIO driver: -22
 | |
| +introduced by the commit 74f4e0cc6108 ("bcma: switch GPIO portions to
 | |
| +use GPIOLIB_IRQCHIP").
 | |
| +
 | |
| +Fixes: f8c55dc6e828 ("MIPS: use generic dma noncoherent ops for simple noncoherent platforms")
 | |
| +Fixes: 74f4e0cc6108 ("bcma: switch GPIO portions to use GPIOLIB_IRQCHIP")
 | |
| +Cc: linux-mips@linux-mips.org
 | |
| +Cc: Christoph Hellwig <hch@lst.de>
 | |
| +Cc: Linus Walleij <linus.walleij@linaro.org>
 | |
| +Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | |
| +---
 | |
| +
 | |
| +--- a/drivers/bcma/host_soc.c
 | |
| ++++ b/drivers/bcma/host_soc.c
 | |
| +@@ -191,6 +191,8 @@ int __init bcma_host_soc_init(struct bcm
 | |
| + 	struct bcma_bus *bus = &soc->bus;
 | |
| + 	int err;
 | |
| + 
 | |
| ++	bus->dev = soc->dev;
 | |
| ++
 | |
| + 	/* Scan bus and initialize it */
 | |
| + 	err = bcma_bus_early_register(bus);
 | |
| + 	if (err)
 | |
| +--- a/drivers/bcma/main.c
 | |
| ++++ b/drivers/bcma/main.c
 | |
| +@@ -236,12 +236,16 @@ EXPORT_SYMBOL(bcma_core_irq);
 | |
| + 
 | |
| + void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
 | |
| + {
 | |
| ++	struct device *dev = &core->dev;
 | |
| ++
 | |
| + 	core->dev.release = bcma_release_core_dev;
 | |
| + 	core->dev.bus = &bcma_bus_type;
 | |
| + 	dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
 | |
| + 	core->dev.parent = bus->dev;
 | |
| +-	if (bus->dev)
 | |
| ++	if (bus->dev) {
 | |
| + 		bcma_of_fill_device(bus->dev, core);
 | |
| ++		dma_coerce_mask_and_coherent(dev, bus->dev->coherent_dma_mask);
 | |
| ++	}
 | |
| + 
 | |
| + 	switch (bus->hosttype) {
 | |
| + 	case BCMA_HOSTTYPE_PCI:
 | |
| diff --git a/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch b/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch
 | |
| new file mode 100644
 | |
| index 0000000000..7e7866add8
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/810-pci_disable_common_quirks.patch
 | |
| @@ -0,0 +1,62 @@
 | |
| +From: Gabor Juhos <juhosg@openwrt.org>
 | |
| +Subject: debloat: add kernel config option to disabling common PCI quirks
 | |
| +
 | |
| +Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
 | |
| +---
 | |
| + drivers/pci/Kconfig  | 6 ++++++
 | |
| + drivers/pci/quirks.c | 6 ++++++
 | |
| + 2 files changed, 12 insertions(+)
 | |
| +
 | |
| +--- a/drivers/pci/Kconfig
 | |
| ++++ b/drivers/pci/Kconfig
 | |
| +@@ -118,6 +118,13 @@ config XEN_PCIDEV_FRONTEND
 | |
| + 	  The PCI device frontend driver allows the kernel to import arbitrary
 | |
| + 	  PCI devices from a PCI backend to support PCI driver domains.
 | |
| + 
 | |
| ++config PCI_DISABLE_COMMON_QUIRKS
 | |
| ++	bool "PCI disable common quirks"
 | |
| ++	depends on PCI
 | |
| ++	help
 | |
| ++	  If you don't know what to do here, say N.
 | |
| ++
 | |
| ++
 | |
| + config PCI_ATS
 | |
| + 	bool
 | |
| + 
 | |
| +--- a/drivers/pci/quirks.c
 | |
| ++++ b/drivers/pci/quirks.c
 | |
| +@@ -205,6 +205,7 @@ static void quirk_mmio_always_on(struct
 | |
| + DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID,
 | |
| + 				PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on);
 | |
| + 
 | |
| ++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
 | |
| + /*
 | |
| +  * The Mellanox Tavor device gives false positive parity errors.  Mark this
 | |
| +  * device with a broken_parity_status to allow PCI scanning code to "skip"
 | |
| +@@ -3320,6 +3321,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_I
 | |
| + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata);
 | |
| + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata);
 | |
| + 
 | |
| ++#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
 | |
| ++
 | |
| + /*
 | |
| +  * Ivytown NTB BAR sizes are misreported by the hardware due to an erratum.
 | |
| +  * To work around this, query the size it should be configured to by the
 | |
| +@@ -3345,6 +3348,8 @@ static void quirk_intel_ntb(struct pci_d
 | |
| + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e08, quirk_intel_ntb);
 | |
| + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0e0d, quirk_intel_ntb);
 | |
| + 
 | |
| ++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
 | |
| ++
 | |
| + /*
 | |
| +  * Some BIOS implementations leave the Intel GPU interrupts enabled, even
 | |
| +  * though no one is handling them (e.g., if the i915 driver is never
 | |
| +@@ -3383,6 +3388,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_IN
 | |
| + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
 | |
| + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq);
 | |
| + 
 | |
| ++#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
 | |
| ++
 | |
| + /*
 | |
| +  * PCI devices which are on Intel chips can skip the 10ms delay
 | |
| +  * before entering D3 mode.
 | |
| diff --git a/target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch
 | |
| new file mode 100644
 | |
| index 0000000000..42a8397839
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/811-pci_disable_usb_common_quirks.patch
 | |
| @@ -0,0 +1,115 @@
 | |
| +From: Felix Fietkau <nbd@nbd.name>
 | |
| +Subject: debloat: disable common USB quirks
 | |
| +
 | |
| +Signed-off-by: Felix Fietkau <nbd@nbd.name>
 | |
| +---
 | |
| + drivers/usb/host/pci-quirks.c | 16 ++++++++++++++++
 | |
| + drivers/usb/host/pci-quirks.h | 18 +++++++++++++++++-
 | |
| + include/linux/usb/hcd.h       |  7 +++++++
 | |
| + 3 files changed, 40 insertions(+), 1 deletion(-)
 | |
| +
 | |
| +--- a/drivers/usb/host/pci-quirks.c
 | |
| ++++ b/drivers/usb/host/pci-quirks.c
 | |
| +@@ -128,6 +128,8 @@ struct amd_chipset_type {
 | |
| + 	u8 rev;
 | |
| + };
 | |
| + 
 | |
| ++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
 | |
| ++
 | |
| + static struct amd_chipset_info {
 | |
| + 	struct pci_dev	*nb_dev;
 | |
| + 	struct pci_dev	*smbus_dev;
 | |
| +@@ -633,6 +635,10 @@ bool usb_amd_pt_check_port(struct device
 | |
| + }
 | |
| + EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
 | |
| + 
 | |
| ++#endif /* CONFIG_PCI_DISABLE_COMMON_QUIRKS */
 | |
| ++
 | |
| ++#if IS_ENABLED(CONFIG_USB_UHCI_HCD)
 | |
| ++
 | |
| + /*
 | |
| +  * Make sure the controller is completely inactive, unable to
 | |
| +  * generate interrupts or do DMA.
 | |
| +@@ -712,8 +718,17 @@ reset_needed:
 | |
| + 	uhci_reset_hc(pdev, base);
 | |
| + 	return 1;
 | |
| + }
 | |
| ++#else
 | |
| ++int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
 | |
| ++{
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++
 | |
| ++#endif
 | |
| + EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
 | |
| + 
 | |
| ++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
 | |
| ++
 | |
| + static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
 | |
| + {
 | |
| + 	u16 cmd;
 | |
| +@@ -1285,3 +1300,4 @@ static void quirk_usb_early_handoff(stru
 | |
| + }
 | |
| + DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID,
 | |
| + 			PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff);
 | |
| ++#endif
 | |
| +--- a/drivers/usb/host/pci-quirks.h
 | |
| ++++ b/drivers/usb/host/pci-quirks.h
 | |
| +@@ -5,6 +5,9 @@
 | |
| + #ifdef CONFIG_USB_PCI
 | |
| + void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
 | |
| + int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
 | |
| ++#endif  /* CONFIG_USB_PCI */
 | |
| ++
 | |
| ++#if defined(CONFIG_USB_PCI) && !defined(CONFIG_PCI_DISABLE_COMMON_QUIRKS)
 | |
| + int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev);
 | |
| + bool usb_amd_hang_symptom_quirk(void);
 | |
| + bool usb_amd_prefetch_quirk(void);
 | |
| +@@ -19,6 +22,18 @@ void sb800_prefetch(struct device *dev,
 | |
| + bool usb_amd_pt_check_port(struct device *device, int port);
 | |
| + #else
 | |
| + struct pci_dev;
 | |
| ++static inline int usb_amd_quirk_pll_check(void)
 | |
| ++{
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++static inline bool usb_amd_hang_symptom_quirk(void)
 | |
| ++{
 | |
| ++	return false;
 | |
| ++}
 | |
| ++static inline bool usb_amd_prefetch_quirk(void)
 | |
| ++{
 | |
| ++	return false;
 | |
| ++}
 | |
| + static inline void usb_amd_quirk_pll_disable(void) {}
 | |
| + static inline void usb_amd_quirk_pll_enable(void) {}
 | |
| + static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
 | |
| +@@ -29,6 +44,11 @@ static inline bool usb_amd_pt_check_port
 | |
| + {
 | |
| + 	return false;
 | |
| + }
 | |
| ++static inline void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev) {}
 | |
| ++static inline bool usb_xhci_needs_pci_reset(struct pci_dev *pdev)
 | |
| ++{
 | |
| ++	return false;
 | |
| ++}
 | |
| + #endif  /* CONFIG_USB_PCI */
 | |
| + 
 | |
| + #endif  /*  __LINUX_USB_PCI_QUIRKS_H  */
 | |
| +--- a/include/linux/usb/hcd.h
 | |
| ++++ b/include/linux/usb/hcd.h
 | |
| +@@ -484,7 +484,14 @@ extern int usb_hcd_pci_probe(struct pci_
 | |
| + extern void usb_hcd_pci_remove(struct pci_dev *dev);
 | |
| + extern void usb_hcd_pci_shutdown(struct pci_dev *dev);
 | |
| + 
 | |
| ++#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
 | |
| + extern int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev);
 | |
| ++#else
 | |
| ++static inline int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *dev)
 | |
| ++{
 | |
| ++	return 0;
 | |
| ++}
 | |
| ++#endif
 | |
| + 
 | |
| + #ifdef CONFIG_PM
 | |
| + extern const struct dev_pm_ops usb_hcd_pci_pm_ops;
 | |
| diff --git a/target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch b/target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
 | |
| new file mode 100644
 | |
| index 0000000000..33eb34c913
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/820-w1-gpio-fix-problem-with-platfom-data-in-w1-gpio.patch
 | |
| @@ -0,0 +1,26 @@
 | |
| +From d9c8bc8c1408f3e8529db6e4e04017b4c579c342 Mon Sep 17 00:00:00 2001
 | |
| +From: Pawel Dembicki <paweldembicki@gmail.com>
 | |
| +Date: Sun, 18 Feb 2018 17:08:04 +0100
 | |
| +Subject: [PATCH] w1: gpio: fix problem with platfom data in w1-gpio
 | |
| +
 | |
| +In devices, where fdt is used, is impossible to apply platform data
 | |
| +without proper fdt node.
 | |
| +
 | |
| +This patch allow to use platform data in devices with fdt.
 | |
| +
 | |
| +Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com>
 | |
| +---
 | |
| + drivers/w1/masters/w1-gpio.c | 7 +++----
 | |
| + 1 file changed, 3 insertions(+), 4 deletions(-)
 | |
| +
 | |
| +--- a/drivers/w1/masters/w1-gpio.c
 | |
| ++++ b/drivers/w1/masters/w1-gpio.c
 | |
| +@@ -76,7 +76,7 @@ static int w1_gpio_probe(struct platform
 | |
| + 	enum gpiod_flags gflags = GPIOD_OUT_LOW_OPEN_DRAIN;
 | |
| + 	int err;
 | |
| + 
 | |
| +-	if (of_have_populated_dt()) {
 | |
| ++	if (of_have_populated_dt() && !dev_get_platdata(&pdev->dev)) {
 | |
| + 		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 | |
| + 		if (!pdata)
 | |
| + 			return -ENOMEM;
 | |
| diff --git a/target/linux/generic/pending-5.10/834-ledtrig-libata.patch b/target/linux/generic/pending-5.10/834-ledtrig-libata.patch
 | |
| new file mode 100644
 | |
| index 0000000000..a52e712d8c
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/834-ledtrig-libata.patch
 | |
| @@ -0,0 +1,149 @@
 | |
| +From: Daniel Golle <daniel@makrotopia.org>
 | |
| +Subject: libata: add ledtrig support
 | |
| +
 | |
| +This adds a LED trigger for each ATA port indicating disk activity.
 | |
| +
 | |
| +As this is needed only on specific platforms (NAS SoCs and such),
 | |
| +these platforms should define ARCH_WANTS_LIBATA_LEDS if there
 | |
| +are boards with LED(s) intended to indicate ATA disk activity and
 | |
| +need the OS to take care of that.
 | |
| +In that way, if not selected, LED trigger support not will be
 | |
| +included in libata-core and both, codepaths and structures remain
 | |
| +untouched.
 | |
| +
 | |
| +Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 | |
| +---
 | |
| + drivers/ata/Kconfig       | 16 ++++++++++++++++
 | |
| + drivers/ata/libata-core.c | 41 +++++++++++++++++++++++++++++++++++++++++
 | |
| + include/linux/libata.h    |  9 +++++++++
 | |
| + 3 files changed, 66 insertions(+)
 | |
| +
 | |
| +--- a/drivers/ata/Kconfig
 | |
| ++++ b/drivers/ata/Kconfig
 | |
| +@@ -67,6 +67,22 @@ config ATA_FORCE
 | |
| + 
 | |
| + 	  If unsure, say Y.
 | |
| + 
 | |
| ++config ARCH_WANT_LIBATA_LEDS
 | |
| ++	bool
 | |
| ++
 | |
| ++config ATA_LEDS
 | |
| ++	bool "support ATA port LED triggers"
 | |
| ++	depends on ARCH_WANT_LIBATA_LEDS
 | |
| ++	select NEW_LEDS
 | |
| ++	select LEDS_CLASS
 | |
| ++	select LEDS_TRIGGERS
 | |
| ++	default y
 | |
| ++	help
 | |
| ++	  This option adds a LED trigger for each registered ATA port.
 | |
| ++	  It is used to drive disk activity leds connected via GPIO.
 | |
| ++
 | |
| ++	  If unsure, say N.
 | |
| ++
 | |
| + config ATA_ACPI
 | |
| + 	bool "ATA ACPI Support"
 | |
| + 	depends on ACPI
 | |
| +--- a/drivers/ata/libata-core.c
 | |
| ++++ b/drivers/ata/libata-core.c
 | |
| +@@ -650,6 +650,19 @@ u64 ata_tf_read_block(const struct ata_t
 | |
| + 	return block;
 | |
| + }
 | |
| + 
 | |
| ++#ifdef CONFIG_ATA_LEDS
 | |
| ++#define LIBATA_BLINK_DELAY 20 /* ms */
 | |
| ++static inline void ata_led_act(struct ata_port *ap)
 | |
| ++{
 | |
| ++	unsigned long led_delay = LIBATA_BLINK_DELAY;
 | |
| ++
 | |
| ++	if (unlikely(!ap->ledtrig))
 | |
| ++		return;
 | |
| ++
 | |
| ++	led_trigger_blink_oneshot(ap->ledtrig, &led_delay, &led_delay, 0);
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| + /**
 | |
| +  *	ata_build_rw_tf - Build ATA taskfile for given read/write request
 | |
| +  *	@tf: Target ATA taskfile
 | |
| +@@ -4513,6 +4526,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
 | |
| + 		if (tag < 0)
 | |
| + 			return NULL;
 | |
| + 	}
 | |
| ++#ifdef CONFIG_ATA_LEDS
 | |
| ++	ata_led_act(ap);
 | |
| ++#endif
 | |
| + 
 | |
| + 	qc = __ata_qc_from_tag(ap, tag);
 | |
| + 	qc->tag = qc->hw_tag = tag;
 | |
| +@@ -5291,6 +5307,9 @@ struct ata_port *ata_port_alloc(struct a
 | |
| + 	ap->stats.unhandled_irq = 1;
 | |
| + 	ap->stats.idle_irq = 1;
 | |
| + #endif
 | |
| ++#ifdef CONFIG_ATA_LEDS
 | |
| ++	ap->ledtrig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
 | |
| ++#endif
 | |
| + 	ata_sff_port_init(ap);
 | |
| + 
 | |
| + 	return ap;
 | |
| +@@ -5326,6 +5345,12 @@ static void ata_host_release(struct kref
 | |
| + 
 | |
| + 		kfree(ap->pmp_link);
 | |
| + 		kfree(ap->slave_link);
 | |
| ++#ifdef CONFIG_ATA_LEDS
 | |
| ++		if (ap->ledtrig) {
 | |
| ++			led_trigger_unregister(ap->ledtrig);
 | |
| ++			kfree(ap->ledtrig);
 | |
| ++		};
 | |
| ++#endif
 | |
| + 		kfree(ap);
 | |
| + 		host->ports[i] = NULL;
 | |
| + 	}
 | |
| +@@ -5732,7 +5757,23 @@ int ata_host_register(struct ata_host *h
 | |
| + 		host->ports[i]->print_id = atomic_inc_return(&ata_print_id);
 | |
| + 		host->ports[i]->local_port_no = i + 1;
 | |
| + 	}
 | |
| ++#ifdef CONFIG_ATA_LEDS
 | |
| ++	for (i = 0; i < host->n_ports; i++) {
 | |
| ++		if (unlikely(!host->ports[i]->ledtrig))
 | |
| ++			continue;
 | |
| + 
 | |
| ++		snprintf(host->ports[i]->ledtrig_name,
 | |
| ++			sizeof(host->ports[i]->ledtrig_name), "ata%u",
 | |
| ++			host->ports[i]->print_id);
 | |
| ++
 | |
| ++		host->ports[i]->ledtrig->name = host->ports[i]->ledtrig_name;
 | |
| ++
 | |
| ++		if (led_trigger_register(host->ports[i]->ledtrig)) {
 | |
| ++			kfree(host->ports[i]->ledtrig);
 | |
| ++			host->ports[i]->ledtrig = NULL;
 | |
| ++		}
 | |
| ++	}
 | |
| ++#endif
 | |
| + 	/* Create associated sysfs transport objects  */
 | |
| + 	for (i = 0; i < host->n_ports; i++) {
 | |
| + 		rc = ata_tport_add(host->dev,host->ports[i]);
 | |
| +--- a/include/linux/libata.h
 | |
| ++++ b/include/linux/libata.h
 | |
| +@@ -23,6 +23,9 @@
 | |
| + #include <linux/cdrom.h>
 | |
| + #include <linux/sched.h>
 | |
| + #include <linux/async.h>
 | |
| ++#ifdef CONFIG_ATA_LEDS
 | |
| ++#include <linux/leds.h>
 | |
| ++#endif
 | |
| + 
 | |
| + /*
 | |
| +  * Define if arch has non-standard setup.  This is a _PCI_ standard
 | |
| +@@ -882,6 +885,12 @@ struct ata_port {
 | |
| + #ifdef CONFIG_ATA_ACPI
 | |
| + 	struct ata_acpi_gtm	__acpi_init_gtm; /* use ata_acpi_init_gtm() */
 | |
| + #endif
 | |
| ++
 | |
| ++#ifdef CONFIG_ATA_LEDS
 | |
| ++	struct led_trigger	*ledtrig;
 | |
| ++	char			ledtrig_name[8];
 | |
| ++#endif
 | |
| ++
 | |
| + 	/* owned by EH */
 | |
| + 	u8			sector_buf[ATA_SECT_SIZE] ____cacheline_aligned;
 | |
| + };
 | |
| diff --git a/target/linux/generic/pending-5.10/840-hwrng-bcm2835-set-quality-to-1000.patch b/target/linux/generic/pending-5.10/840-hwrng-bcm2835-set-quality-to-1000.patch
 | |
| new file mode 100644
 | |
| index 0000000000..580f0b1bfa
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/840-hwrng-bcm2835-set-quality-to-1000.patch
 | |
| @@ -0,0 +1,26 @@
 | |
| +From d6988cf1d16faac56899918bb2b1be8d85155e3f Mon Sep 17 00:00:00 2001
 | |
| +From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
 | |
| +Date: Sat, 20 Feb 2021 18:36:38 +0100
 | |
| +Subject: [PATCH] hwrng: bcm2835: set quality to 1000
 | |
| +MIME-Version: 1.0
 | |
| +Content-Type: text/plain; charset=UTF-8
 | |
| +Content-Transfer-Encoding: 8bit
 | |
| +
 | |
| +This allows devices without a high precission timer to reduce boot from >100s
 | |
| +to <30s.
 | |
| +
 | |
| +Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
 | |
| +---
 | |
| + drivers/char/hw_random/bcm2835-rng.c | 1 +
 | |
| + 1 file changed, 1 insertion(+)
 | |
| +
 | |
| +--- a/drivers/char/hw_random/bcm2835-rng.c
 | |
| ++++ b/drivers/char/hw_random/bcm2835-rng.c
 | |
| +@@ -163,6 +163,7 @@ static int bcm2835_rng_probe(struct plat
 | |
| + 	priv->rng.init = bcm2835_rng_init;
 | |
| + 	priv->rng.read = bcm2835_rng_read;
 | |
| + 	priv->rng.cleanup = bcm2835_rng_cleanup;
 | |
| ++	priv->rng.quality = 1000;
 | |
| + 
 | |
| + 	if (dev_of_node(dev)) {
 | |
| + 		rng_id = of_match_node(bcm2835_rng_of_match, dev->of_node);
 | |
| diff --git a/target/linux/generic/pending-5.10/920-mangle_bootargs.patch b/target/linux/generic/pending-5.10/920-mangle_bootargs.patch
 | |
| new file mode 100644
 | |
| index 0000000000..9008a88e2e
 | |
| --- /dev/null
 | |
| +++ b/target/linux/generic/pending-5.10/920-mangle_bootargs.patch
 | |
| @@ -0,0 +1,71 @@
 | |
| +From: Imre Kaloz <kaloz@openwrt.org>
 | |
| +Subject: init: add CONFIG_MANGLE_BOOTARGS and disable it by default
 | |
| +
 | |
| +Enabling this option renames the bootloader supplied root=
 | |
| +and rootfstype= variables, which might have to be know but
 | |
| +would break the automatisms OpenWrt uses.
 | |
| +
 | |
| +Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
 | |
| +---
 | |
| + init/Kconfig |  9 +++++++++
 | |
| + init/main.c  | 24 ++++++++++++++++++++++++
 | |
| + 2 files changed, 33 insertions(+)
 | |
| +
 | |
| +--- a/init/Kconfig
 | |
| ++++ b/init/Kconfig
 | |
| +@@ -1791,6 +1791,15 @@ config EMBEDDED
 | |
| + 	  an embedded system so certain expert options are available
 | |
| + 	  for configuration.
 | |
| + 
 | |
| ++config MANGLE_BOOTARGS
 | |
| ++	bool "Rename offending bootargs"
 | |
| ++	depends on EXPERT
 | |
| ++	help
 | |
| ++	  Sometimes the bootloader passed bogus root= and rootfstype=
 | |
| ++	  parameters to the kernel, and while you want to ignore them,
 | |
| ++	  you need to know the values f.e. to support dual firmware
 | |
| ++	  layouts on the flash.
 | |
| ++
 | |
| + config HAVE_PERF_EVENTS
 | |
| + 	bool
 | |
| + 	help
 | |
| +--- a/init/main.c
 | |
| ++++ b/init/main.c
 | |
| +@@ -607,6 +607,29 @@ static inline void setup_nr_cpu_ids(void
 | |
| + static inline void smp_prepare_cpus(unsigned int maxcpus) { }
 | |
| + #endif
 | |
| + 
 | |
| ++#ifdef CONFIG_MANGLE_BOOTARGS
 | |
| ++static void __init mangle_bootargs(char *command_line)
 | |
| ++{
 | |
| ++	char *rootdev;
 | |
| ++	char *rootfs;
 | |
| ++
 | |
| ++	rootdev = strstr(command_line, "root=/dev/mtdblock");
 | |
| ++
 | |
| ++	if (rootdev)
 | |
| ++		strncpy(rootdev, "mangled_rootblock=", 18);
 | |
| ++
 | |
| ++	rootfs = strstr(command_line, "rootfstype");
 | |
| ++
 | |
| ++	if (rootfs)
 | |
| ++		strncpy(rootfs, "mangled_fs", 10);
 | |
| ++
 | |
| ++}
 | |
| ++#else
 | |
| ++static void __init mangle_bootargs(char *command_line)
 | |
| ++{
 | |
| ++}
 | |
| ++#endif
 | |
| ++
 | |
| + /*
 | |
| +  * We need to store the untouched command line for future reference.
 | |
| +  * We also need to store the touched command line since the parameter
 | |
| +@@ -868,6 +891,7 @@ asmlinkage __visible void __init __no_sa
 | |
| + 	pr_notice("%s", linux_banner);
 | |
| + 	early_security_init();
 | |
| + 	setup_arch(&command_line);
 | |
| ++	mangle_bootargs(command_line);
 | |
| + 	setup_boot_config(command_line);
 | |
| + 	setup_command_line(command_line);
 | |
| + 	setup_nr_cpu_ids();
 | |
| -- 
 | |
| 2.25.1
 | |
| 
 | 
